107. python高级------闭包与装饰器(2)
python修炼第二十四天
2019年 4月 23日 晴
内容回顾
1.可变与不可变类型
1.元组
"""可变/不可变类型的区别: += 运算"""
# 列表和元组是可以使用加法运算符
a = (10,20)
b = (30,40)
print(id(a))
print(id(b))
a = a + b
a += b # 对于元组而言,加法运算和加等运算效果相等,都是生成一个新的元组
print(id(a))
print(a) # 得到的新的a的地址和原来的a的地址相等
2.列表
a = [10,20]
b = [30,40]
print(id(a))
print(id(b))
a = a + b # 列表加法运算时,生成一个新的列表
a += b # 列表进行加等运算时, 在原列表中添加了元素, 而没有生成新的列表(相当于列表的extend方法)
print(id(a))
print(a)
2.实参的使用
形参前面加* ,表示标识形参为可变参数; 实参前面加* ,可以将容器格式进行转化
def func1(*args,**kwargs):
print(args)
print(kwargs)
def func2(*args,**kwargs):
func1(args,kwargs) # func1(1,2,3),{"m": 10,"n": 20}
func2(1,2,3,m=10,n=20)
(( 1, 2, 3 ) , { ’ n’ : 20 , ’ m ’ : 10})
{}
说明:
在执行func2时,先将参数传给func2形参,即*args
得到1,2,3
而**kwargs
得到 m=10, n = 20;func2将形参传给func1的形参时func1参数列表变成 :((1,2,3),{"m": 10,"n": 20})
,func1的形参只是一个元组,于是当该元组传参给func1(*args,**kwargs)
时,会被第一个*args
可变形参接收,而**kwargs
接收不到任何值.因此输出的结果第一个为(( 1, 2, 3 ) , { ' n' : 20 , ' m ' : 10})
,第二个为{}
为了解决上述问题, 引出实参前面加*
的方法
引例
def func1(a,b,c)
print(a)
print(b)
print(c)
func1(1,2,3)
1
2
3
结果显而易见
但是如果是这样呢?
def func1(a,b,c)
print(a)
print(b)
print(c)
tuple1 = (1,2,3)
func1(tuple1)
结果报错
将上述代码改变
# 其他不变
func1(*tuple1) # *(1,2,3) -> 1,2,3
结果
1
2
3
这里将容器(1,2,3)
加*
后进行格式转换1,2,3
注意:这不是解包
同样列表也可以
def func1(a,b,c)
print(a)
print(b)
print(c)
list1 = (1,2,3)
func1(list1)
字典也行
def func1(a,b,c)
print(a)
print(b)
print(c)
dict = {"a": 10, "b": 20, "c": 30}
func1(**dict1) # **{"a": 10, "b": 20, "c": 30} -> a=10,b=20,c=30
注意: 字典容器格式转换要加两个
*
,即**kwargs
** {"m":10 , "n":20 }
解决问题
由引例可以知道,要想使**kwargs
得到值{"m":10,"n":20}
,则需要使用实参前面加*
,使其容器发生转化
def func1(*args,**kwargs)
print(args)
print(kwargs)
def func2(*args,**kwargs)
func1(*args,**kwargs) # 在元组和字典前加 * 得到相当于func1(1,2,3,m=10,n=20)
func2(1,2,3,m=10,n=20)
打印func1的kwargs
时会得到{"m":10 , "n":20 }
问题解决!