函数动态参数,作用域
本节主要内容
1,函数参数--动态参数
2,名称空间,局部名称空间,全局名称空间,作用域,加载顺序
3,函数的嵌套
4,global,nonlocal
一,函数参数--动态参数
形参的动态参数:
1,动态接受位置参数
def chi(*food): print('我要吃', food) chi('大米', '小米') # 结果 # 我要吃 ('大米', '小米') 多个参数传递进去,收到的内容是元组tuple
注意:动态接受参数的时候要注意:动态参数必须在位置参数的后面
否则,动态参数放置到前面,动态参数会接受到所有的参数,位置参数不会有任何值,报错
def chi(*food, a, b): print('我要吃', food, a, b) chi('大米饭', '小米饭', a = '馒头', b = '面条') # 必须要用关键词参数指定
默认值永久都生效
def chi(a, b, *food, c='哈哈哈'): print(a, b, food, c)
2,动态接受关键字参数
在python中可以动态的位置参数,但是,这种情况中能接受位置参数无法接受关键字参数,在python中使用**来接受关键字参数
def func(**kwargs): print(kwargs) func(a=1, b=2, c=3) func(a=1, b=2) # {'a': 1, 'b': 2, 'c': 3} # {'a': 1, 'b': 2}
这个时候接受的是个dict
顺序的问题,在函数调用的时候,如果先给出关键字参数,则整个参数列表会报错.
def func(a,b,c,d): print(a,b,c,d) func(1,2,c=3,4) # SyntaxError: positional argument follows keyword argument
关键字参数必须在位置参数后面,否则参数会混乱
所以关键字参数必须在位置参数的后面,由于实参是这个顺序,所以形参接受的时候也是这个顺序,也就是说位置参数必须在关键字参数前面,动态接受关键字参数也要在后面
最终顺序:
位置参数>*args>默认值参数>**kwargs
接受所有的参数
def func(*args, **kwargs): print(args, kwargs) func('陈润', '周杰伦', lbj="老北京")
在实参位置上给一个序列,列表,可迭代对象前面加个*表示把这个序列按顺序打散
在形参的位置上的*表示把接收到的参数组合成一个元组
如果是一个字典,那么也可以打散,不过需要用两个
def func(**kwargs): print(kwargs) dic = {'a': 1, 'b': 2} func(**dic)
二,命名空间
在python解释器开始执行之后,就会在内存中开辟一个空间,每当遇到一个变量的时候,就把变量名和值之间的关系记录下来,但是当遇到函数定义的时候,解释器只是把函数读入内存,表示这个函数存在了,至于函数内部的变量和逻辑,解释器不关心,也就是说一开始的时候函数只是加载进来,仅此而已,只有当函数被调用和访问的时候,解释器才会根据函数内部声明的变量来进行开辟变量的内部空间,随着函数执行完毕,这些函数内部变量占用的空间也会随着函数执行完毕被清空.
def fun(): a = 10 print(a) fun() print(a) # a不存在了
我们给存放名字和值的关系的空间起一个名字叫:命名空间.我们的变量在存储的时候就是存储在这篇空间中的.
命名空间分类:
1,全局命名空间-->我们直接在py文件中,函数外声明的变量都属于全局命名空间
2,局部命名空间-->在函数中声明的变量会放在局部命名空间
3,内置命名空间-->存放python解释器为我们提供的名字,list,tuple,str,int这些都是内置命名空间
加载顺序:
1,内置命名空间
2,全局命名空间
3,内置命名空间
a = 10 def func(): a = 20 print(a) func() # 20
作用域:作用域就是作用范围,按照生效范围来看分为,全局作用域和局部作用域
全局作用域:包含内置命名空间和全局命名空间.在整个文件的任何位置都可以使用(遵循从上到下逐行执行).局部作用域:在函数内部可以使用
作用域命名空间:
1,全局作用域:全局命名空间+内置命名空间
2,局部作用域:局部命名空间
我们可以通过globals()函数来查看全局作用域中的内容,也可以通过local()来查看局部作用域中的变量和函数信息
a = 10 def func(): a = 40 b = 20 def abc(): print('哈哈') print(a, b) # 这里使用的是局部作用域 print(globals()) # 打印全局作用域中的内容 print(locals()) # 打印局部作用域中的内容 func()
三,函数的嵌套
1,只要遇见了()就是函数的调用,如果没有()就不是函数的调用
2,函数的执行顺序
四,关键字global和nonlocal
global表示,不再使用局部作用域中的内容,而改用全局作用域中的变量
nonlocal表示在局部作用域中,调用父级命名空间中的变量
a = 1 def fun_1(): a = 2 def fun_2(): nonlocal a # a = 2 a = 3 # fun_1 中的a变成了3 def fun_3(): a = 4 print(a) print(a) # a = 3 fun_3() # a = 4 print(a) # a = 3 print(a) # a = 2 fun_2() print(a) # a = 3 print(a) # 1 fun_1() print(a) # 1 # 结果:1,2,3,4,3,3,1