*args和**kwargs
# *代表聚合,他将所有位置参数聚合成一个元组,赋值给args
# **将所有‘关键字’参数聚合到一个字典中,将这个字典赋值给kwargs
def func(*args, **kwargs):
print(*args)
print(**kwargs)
func(*[1,2,3], *[4,5,6]) # 等同于 func(1,2,3,4,5,6)
func(**{'name': 'alex'},**{'age':100}) # 等同于 func(name='alex',age=100)
# 在调用时*代表打散
形参顺序
def func(a,b,*args,sex= '男',c,**kwargs,):
print(a,b)
print(sex)
print(args)
print(c)
print(kwargs)
func(1,2,3,4,5,6,sex="女",c='666',name="alex",age=100)
# 位置参数,args,默认参数,关键字参数,kwargs
命名空间
执行顺序:
内置名称空间,全局名称空间,局部名称空间(函数执行时)
取值顺序:
就近原则,单项不可逆
局部作用域可以应用全局作用域变量,但是不可进行修改
原因:当python解释器读取到局部作用域时,发现了你对一个变量进行修改的操作,解释器会认为你在局部已经定义过这个局部变量了,他就从局部找这个局部变量,报错了。
count = 1
def func():
print(count)
count = 3
func()
# 这种会报错,语法错误。一定要先定义后引用
当参数为可变类型的坑
def func(a, b=[]):
b.append(a)
return b
print(func(10,)) # [10]
print(func(20, [])) # [20]
print(func(30,)) # [10, 30]
# 如果默认参数为可变类型,那么无论调用多少次这个默认参数,都是同一个
def func2(a, b=[]):
b.append(a)
return b
ret1 = func2(10,)
ret2 = func2(20, [])
ret3 = func2(30,)
print(ret1) # [10, 30]
print(ret2) # [20]
print(ret3) # [10, 30]
global nonlocal
# global:在局部作用域声明一个全局变量
name = 'alex'
def func():
global name
name = '太白'
print(name) # alex
func()
print(name) # 太白
# nonlocal: 内层函数对外层函数的局部变量进行修改
count = 1
def wrapper()
count = 1
def inner():
nonlocal count
count += 1
print(count) # 1
inner()
print(count) # 2
wrapper()