一.函数的动态的动态参数

动态参数分为两种:动态接收位置参数、动态接收关键字参数。

1.*args  位置参数动态传参

#  顺序: 位置参数=>*args(arguments) => 默认值参数
# * 在这里表示接收位置参数的动态传参, 接收到的是元组
def chi(name,*food, location="天津"): # 参数名是food *表示动态传参
print(location)
print(name+"要吃", food) chi("juan","驴打滚","二姑包子","桂顺斋","长春") #长春
#juan要吃("驴打滚","二姑包子","桂顺斋")

动态接收参数的时候要注意:动态参数必须在位置参数后面。具体请看下面几个示例:

 def chi(*food, a, b):
print("我要吃", food, a, b)
chi("大米饭", "小米饭", "黄瓜", "茄子")
# 这时程序会报错,因为前面传递的所有位置参数都被*food接收了,a和b永远接收不到参数
# TypeError: chi() missing 2 required keyword-only arguments: 'a' and 'b' # 所以上例可以改成以下代码
def chi(*food,a,b):
print("我要吃",food,a,b)
chi("大米饭","小米饭",a="黄瓜",b="茄子") # 必须用关键字参数来指定
# 这时候a和b就有值了,但是这样写的话位置参数就不能用了, # 所以,我们要先写位置参数,然后再用动态参数
def chi(a,b,*food):
print("我要吃",a,b,food)
chi("大米饭","小米饭","馒头","面条")
# 结果为:我要吃 大米饭 小米饭 ('馒头', '面条')
# 前面两个参数用位置参数来接收,后面的参数用动态参数接收
def chi(a,b,c="馒头",*food):
print(a,b,c,food)
chi("香蕉","菠萝") # 香蕉 菠萝 馒头 ()默认值生效
chi("香蕉","菠萝","葫芦娃") # 香蕉 菠萝 葫芦娃() 默认值不生效
chi("香蕉","菠萝","葫芦娃","口罩") # 香蕉 菠萝 葫芦娃("口罩",)默认值不生效
# 我们发现默认值参数写在动态参数前面,默认值只有一种情况可能会生效。
# 即默认值生效时,其后的动态参数接收的参数一定是0个 def chi(a,b,*food,c="娃哈哈"):
print(a,b,food,c)
chi("香蕉","菠萝") #香蕉 菠萝 ()娃哈哈 你默认值生效
chi("香蕉","菠萝","葫芦娃") #香蕉 菠萝 ("葫芦娃",) 娃哈哈 默认值生效
chi("香蕉","菠萝","葫芦娃","口罩") #香蕉 菠萝 ("葫芦娃","口罩")娃哈哈 默认值生效
# 将默认值参数放在动态参数之后,我们发现所有的默认值都生效了,
# 这时候如果不给出关键字传参,那么你的默认值是永远都生效的。

综上可得参数顺序:位置参数,*args(动态接收位置参数),默认值参数

2,动态接收关键字参数   **kwargs
在python中可以动态传参,但是*args这种情况只能接收位置参数,无法接收关键字参数 使用关键字参数的动态传参:就是用**kwargs来接收动态关键字参数,具体示例如下:
    def func(**kwargs):
print(kwargs)
func(a=1,b=2,c=3) # 结果为:{'a': 1, 'b': 2, 'c': 3}
func(a=1,b=2) # 结果为:{'a': 1, 'b': 2}
# 这时候接收的是一个dict字典

最终可得形参顺序:位置参数  >  *args  >  默认值参数  >  **kwargs,这四种参数可以任意进行使用。

   # 如果想要接收所有的参数可以这样写
# 当你不知道需要需要传递多少参数的时候可这样写,
# 因为这样可以传递任意参数,即无敌
def func(*args,**kwargs):
print(args,kwargs)
func("麻花藤","马云",wtf="胡辣汤")

3,动态参数的聚合与实参的打散

  综上可知,在形参位置上*表示把接收到的位置参数聚合(组合)成一个元组,**表示把接收到的关键字参数聚合(组合)成一个字典,那么在实参位置上给一个字符串,列表,元组或者集合(可迭代对象即可),并在其前面加个*表示把这个序列打散,如果是一个字典,则在其前面加上**。具体示例如下:

def fun(*args):
print(args)
lst = [1,4,7]
# fun(lst[0],lst[1],lst[2])
fun(*lst) # 可以使用*把一个列表按顺序打散
s = "臣妾做不到"
fun(*s) # 字符串也可以打散(可迭代对象即可) def fun(**kwargs):
print(kwargs)
dic = {"a":1,"b":2}
fun(**dic)

4,函数的注释(文档注释)

 def chi(food,drink):
"""
这里是函数的注释,先写一下当前这个函数是干什么的,比如我这个函数就是一个吃
:param food: 参数food是什么意思
:param drink: 参数drink是什么意思
:return: 返回的是什么东东
"""
print(food,drink)
return "very good"

二、命名空间

   def fun():
a =10
print(a)
fun()
print(a) # a不存在了已经

命名空间的分类:

  1,全局命名空间-->我们直接在py文件中,函数外声明的变量都属于全局命名空间;

  2,局部命名空间-->在函数中声明的变量会放在局部命名空间;

  3,内置命名空间 -->存放python解释器为我们提供的名字,如int,str,list这些都是内置命名空间;

加载顺序:

  1,内置命名空间

  2,全局命名空间

  3,局部命名空间(函数被执行的时候)

取值顺序:

  1,局部命名空间

  2,全局命名空间

  3,内置命名空间

 a = 10
def dunc():
a = 20
print(a)
dunc() #结果为:20

作用域:作用域就是作用范围,按照生效范围来看分为全局作用域和局部作用域。

全局作用域:包含内置命名空间和全局命名空间,在整个文件的任何位置都可以使用(遵循从上到下逐行执行);

局部作用域:在函数内部可以使用;

我们可以通过globals()函数来查看全局作用域中的内容,也可以通过locals()来查看局部作用域中的变量和函数信息,具体示例如下:

a = 10
def func():
a = 40
b = 20
def abc():
print("哈哈")
print(a,b) # 这里使用的是局部作用域
print(globals()) #打印全局作用域中的内容
print(locals()) #打印局部作用域中的内容
func()

三,函数的嵌套

1,只要遇见了( )就是函数的调用,如果没有( )就不是函数的调用。

2,函数的执行顺序,具体示例如下:

#函数的嵌套
def fun2():
print(222)
def fun3():
print(666)
print(444)
fun3()
print(888)
print(33)
fun2()
print(555)
# 结果为:
# 33
# 222
# 444
# 666
# 888
#

四、关键字global和nonlocal

现在我们写这样一个代码,首先在全局声明一个变量,然后在局部调用这个变量,并改变这个变量的值,具体如下:

 a = 10
def func():
global a # 这里用的a是全局的
a = 20
print(a)
func()
print(a) # 结果为:20 20 def func():
global a #加global 表示不在局部创建这个变量,而是直接使用全局的a
# 若不存在全局变量a,则创建一个全局变量a
a = 28
print(a)
func()
print(a) # 结果为:28 28

global:

  1,声明一个全局变量;

2,在局部作用域想要对全局作用域的全局变量进行修改时,需要用到 global(限于字符串,数字);

def func():
global a
a = 3
func()
print(a) # 结果为:3 count = 1
def search():
global count
count = 2
search()
print(count) # 结果为:2

注意:对可变数据类型(list,dict,set)可以直接引用,不用通过global也能改变。具体如下:

 li = [1,2,3]
dic = {'a':'b'}
def change():
li.append('a')
dic['q'] = 'g'
print(dic)
print(li)
change()
print(li)
print(dic)
# 结果为:
# {'a': 'b', 'q': 'g'}
# [1, 2, 3, 'a']
# [1, 2, 3, 'a']
# {'a': 'b', 'q': 'g'}

nonlocal :

  1,不能修改全局变量;

  2,在局部作用域中,对父级作用域(或者更外层作用域且非全局作用域)的变量进行引用和修改,并且引用的哪层,从那层及以下此变量全部发生改变。具体示例如下:

 a = 10
def func1():
a = 20
def func2():
nonlocal a
a = 30
print(a)
func2()
print(a)
func1()
# 结果:
# 加了nonlocal
#
#
# 不加nonlocal
#
#

练习,如果嵌套了很多层,会是一种什么效果,分析明白,那么作用域,global ,nonlocal 就没问题了:

a = 1
def fun_1():
a = 2
def fun_2():
nonlocal a
a = 3
def fun_3():
a = 4
print(a)
print(a)
fun_3()
print(a)
print(a)
fun_2()
print(a)
print(a)
fun_1()
print(a)
# 结果:
#
#
#
#
#
#
												

python-函数进阶-动态传参,名称空间,作用域的问题的更多相关文章

  1. python函数的动态传参.作用域与命名空间

    一.动态传参1.*表示动态传参. 可以接受所有的位置参数传参的时候自动的把实参打包成元组 交给形参 def chi(*food): print(food) chi() # 动态传参可以不传参数 chi ...

  2. python之路--动态传参,作用域,函数嵌套

    一 . 动态传参(重点)  * ,  ** * 与 ** * 在形参位置. * 表示不定参数, 接收的是位置参数 接收到的位置参数的动态传参: 都是元组 def eat(*food): # 在形参这里 ...

  3. python记录_day10 动态传参 命名空间 作用域

    一.动态传参 动态传参用到 *args 和 **kwargs ,*号表示接收位置参数,args是参数名:**表示接收关键字参数,kwargs是参数名 def chi(*food): print(foo ...

  4. Python函数定义及传参方式

    主要内容:     1.函数初识     2.函数传参方式        (1)位置参数        (2)默认参数        (3)关键参数        (4)非固定传参 一.函数初识 1. ...

  5. python函数关键字实参传参

    #!/usr/bin/python #coding=utf-8 #好好学习,天天向上 def describe_pet(type,name): print(f"i have a {type} ...

  6. python函数位置实参传参

    #!/usr/bin/python #coding=utf-8 #好好学习,天天向上 def describe_pet(type,name): print(f"i have a {type} ...

  7. python(动态传参、命名空间、函数嵌套、global和nonlocal关键字)

    一.函数的动态传参 1.*args位置参数动态传参 def chi(*food): print(food) chi("烧烤","火锅","虾吃虾涮&q ...

  8. python-函数-动态传参,作用域的问题,函数嵌套,global nonlocal

    ⼀. 函数参数--动态传参 之前我们说过了传参, 如果我们需要给⼀个函数传参, ⽽参数⼜是不确定的. 或者我给⼀个 函数传很多参数, 我的形参就要写很多, 很⿇烦, 怎么办呢. 我们可以考虑使⽤动态参 ...

  9. 函数动态传参,命名空间,gloabal,nonlocal关键字

    一.函数参数->动态传参(形参的第三种) 动态参数分为两种: 1)动态接收位置参数 普通的位置传参: def func(quality_food,junk_food): print('我要吃', ...

随机推荐

  1. poj 1363 Rails (【栈的应用】 刘汝佳的写法 *学习)

    Rails Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 25964   Accepted: 10199 Descripti ...

  2. uva 401 Palindromes 解题报告

    题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  3. 未知USB设备 端口重置失败

    1.开启手机中USB调试 进入“设置”->“应用程序”->“开发”勾选“USB调试程序”.这样设备才可以通过USB连线时被PC识别到. 2.安装驱动 要将Android手机连接到PC需要安 ...

  4. HihoCoder 1473 : 小Ho的强迫症( 欧几里得 )

    描述 小Ho在一条笔直的街道上散步.街道上铺着长度为L的石板,所以每隔L距离就有一条石板连接的缝隙,如下图所示. 小Ho在散步的时候有奇怪的强迫症,他不希望脚踩在石板的缝隙上.(如果小Ho一只脚的脚尖 ...

  5. HDU2147 kiki's game (SG表找规律)

    Recently kiki has nothing to do. While she is bored, an idea appears in his mind, she just playes th ...

  6. UVA562(01背包均分问题)

    Dividing coins Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Descriptio ...

  7. synergy的配置使用

    1.http://blog.csdn.net/qq_16618179/article/details/54094636 2.两个版本要一致 3.synergy  fail to connect sec ...

  8. Notice:Array to string conversion的问题

    如果后台或者前端输出这样的提示: Notice: Array to string conversion 原因是:用 echo  来输出数组,当然会报错,数组应该用print , print_r , 或 ...

  9. 【Linux学习】Linux文件系统5—查看文件内容命令

    Linux文件系统5-查看文件内容命令 cat: 由第一行开始显示文件内容 more: 一页一页地显示文件内容,空格键可以继续翻页显示下一页内容 less:与more类似,但是可以往前翻页 head: ...

  10. 【Linux学习】Linux文件系统4—Linux文件硬链接与软连接

    Linux文件系统4-Linux文件硬链接与软连接 inode:索引节点 (连接文件)link 一.文件硬链接 1.Linux文件系统中,inode只相同的文件是硬链接文件 2.不同文件名,inode ...