动态参数、名称空间、作用域
动态参数
形实参数量
相等
当实参数量与形参数量相等时,参数传递正常。
def func1(a, b, c): pass
func1(1, 2, 3)
不等
当实参数量与形参数量不相等时,则会报错。
def func1(a, b, c): pass
func1(1, 2, 3, 4, 5, 6, 6)
形参
用户传入到函数中的实参数量不确定时,或者为了以后扩展,此时要用到动态参数 *args、**kwargs(万能参数)。
顺序
形参中所有参数的完整排序为:位置参数,*args,默认参数,**kwargs。当然,不是所有的函数都会将这些所有的参数都是用到,有些就是使用其中的几种。
参数
*args
*args用来接收所有的位置参数。例如:
def func(*args, **kwargs): print(args) print(kwargs)
func(1, 2, 3, 4)
其输出结果为:
注意:
print()里面的args前面不能带 * 。
**kwargs
**kwargs接收所有的关键字参数。例如:
def func(*args, **kwargs): print(args) print(kwargs)
func(x=4, y=5, z=6)
打印结果:
注意:
print()里面的kwargs前面不能带 * 。
def func(*args, **kwargs): print(args) print(kwargs)
func(1, 2, 3, x=4, y=5, z=6)
使用方式
位置参数,默认参数
位置参数,默认参数
def func2(a, b, sex = '男'): print(a) print(b) print(sex)
func2(1, 2, '女')
位置参数、*args、默认参数
位置参数、*args、默认参数
def func2(a, b,*args, sex = '男'): print(a) print(b) print(args) print(sex)
func2(1, 2, 5,6,7,8,9, sex='女')
位置参数、*args、默认参数、**kwargs
位置参数、*args、默认参数、**kwargs
def func2(a, b, *args, sex='男',age=20, **kwargs): print(a) print(b) print(args) print(sex) print(age) print(kwargs)
func2(1, 2, 5, 6, 7, 8, 9, x=6, y=5, name='alex')
注意
单纯运行如下函数不会报错。
def func(*args,**kwargs): pass func()
*的魔性用法
聚合
* 在函数定义的时候,代表聚合。
加法器
使用*args简单实现加法器,如下:
def sum1(*args): ret = 0
for i in args: ret += i
return ret
print(sum1(1, 2, 3,))
结果:
实例二:
def func3(*args, **kwargs): print(args) print(kwargs)
l1 = [1, 2, 3] l2 = [11, 21, 32]
func3(l1, l2)
def func3(*args,**kwargs): print(args)
func3(1, 2, 3, 1, 2, 3, 11, 22, 33)
def func3(*args,**kwargs): print(args) print(kwargs)
func3(1,2,3,1,2,3,11,22,33)
print()函数无法接收动态参数,所以当print(**kwargs)时就会报错。
def func1( **kwargs): print(**kwargs)
func1(**{'name':'alex'})
打散
*在函数的执行的时候,代表打散。
def func3(*args, **kwargs): print(args) print(kwargs)
l1 = [1, 2, 3] tu1 = (1, 2, 3) tu2 = (11, 22, 33)
func3(*l1, *tu1, *tu2)
def func3(*args,**kwargs): print(args) print(kwargs)
l1 = [1, 2, 3] dic ={'name': 'alex'} dic1 ={'age': 1000}
func3(*l1, **dic, **dic1)
def func3(*args,**kwargs): # 函数的定义 *用意是聚合。 print(args) print(kwargs)
l1 = [1, 2, 3] tu1 = (1, 2, 3) tu2 = (11, 22, 33)
func3(*l1, *tu1, *tu2)
def func3(*args,**kwargs): print(args) print(kwargs)
l1 = [1, 2, 3] dic ={'name': 'alex'} dic1 ={'age': 1000}
func3(*l1, **dic, **dic1)
名称空间
名称空间包括内置名称空间、全局名称空间、局部名称空间。
空间名称
当程序运行时,代码从上至下一次读取,遇到变量与值,它会在内存中开辟一个空间,存放变量与值的内存地址的对应关系。这样存储变量与值得对应关系的空间叫做名称空间(命名空间)。
临时空间名称
当解释器遇到函数时,他会将函数名存储在内存中,但是对于函数体莫不关心。当函数执行时,他会通过函数名找到函数体,然后将函数体里面的变量等对应关系存放在一个临时开辟的空间中,随着函数的结束,临时的空间关闭,这样的空间叫做临时名称空间。
作用域
全局作用域
全局作用域包括内置名称空间、全局名称空间。
局部作用域
局部作用域包括局部名称空间。
加载顺序
内置名称空间 -----> 全局名称空间(程序运行时) -----> 局部名称空间(函数执行时)
取值顺序
局部名称空间(函数执行时) -----> 全局名称空间(程序运行时) -----> 内置名称空间
执行顺序
当代码运行时,从上至下依次执行。
name = 'girl' def func1(): global name name = 'alex' func1() print(name)
global、nonlocal
global
- 声明一个全局变量;
- 更改一个全局变量。
nonlocal
- 不能改变一个全局变量;
- 在局部作用域中,对父级作用域(或者更外层作用域非全局作用域)的变量进行引用和修改,并且引用的哪层,从那层及以下此变量全部发生改变。
def add_b(): b = 42 def do_global(): b = 10 print(b) # b = 10 def dd_nonlocal(): nonlocal b b = b + 20 print(b) # b = 30 dd_nonlocal() print(b) # b = 30 do_global() print(b) # b = 42 add_b()