上次发布后,后台有粉丝留言,说不太明白这个args 和*kwargs 的用法。其实这个问题经常在面试中被问到,以前是靠死记硬背,还经常记混,记得老师教过,这是可变参数,*args 是把参数变成元组,**kwargs 是转成字典。真是这样吗?还是实践一下吧:
''' *args又叫可变参数,
会把参数解析成tuple,
**kwargs又叫关键字参数,
会把key=value这样的键值对
参数解析成dict,至于叫什么随意,
args和kwargs只是约定俗成,前面有
*和**就行,比如我就叫*anything'''
def func(a,b=1,*anything):
print(a)
print(b)
print("args:",anything)
def funca(**kwargs):
print("kwargs:",kwargs)
def funcb(*anything,**anything):
print("args=",args)
print("anything=",anything)
if __name__ == "__main__":
func(0,1,'无敌哥流批',[22,33],44)
print("---我是分割线---")
funca(a=1,b=2,c=3)
print("---我是分割线---")
funcb([0,1,"t"],1,None,a=1,b=2,c=3)
运行结果:
0
1
args: ('无敌哥流批', [22, 33], 44)
---我是分割线---
kwargs: {'a': 1, 'b': 2, 'c': 3}
---我是分割线---
args= ([0, 1, 'test'], 1, None)
anything= {'a': 1, 'b': 2, 'c': 3}
结果和预想的一样,但是他们其实是有顺序的,固定参数>默认参数>可变参数>关键字参数,搞乱顺序,结果就是
SyntaxError: positional argument
follows keyword argument
老实说,无敌哥这个作业给我看懵了,没明白他的意思,什么是@loop,@loop(5) 又是怎么来的,这俩还是同一个装饰器么?直到看了他的解答才恍然大悟:
def run(times):
'''这个callable方法是核心'''
if callable(times):
def wrapper(*args, **kwargs):
for i in range(5):
times(*args, **kwargs)
print(f"运行的第{i}次")
return wrapper
else:
def decorator(func):
def wrapper(*args, **kwargs):
for i in range(times):
func(*args, **kwargs)
print(f"运行的第{i}次")
return wrapper
return decorator
'''没有加参数,callable是True,会运行5次'''
@run
def func():
print("func运行了")
'''此时callable是False,则会按照传参运行相应次数'''
@run(1)
def func1():
print("func1运行了")
if __name__=="__main__":
func()
print("---我是分割线---")
func1()
原来是利用了 callable 这个方法,来判断函数是否是可以调用的,相当于变相搞了一个 if else 的判断,如果是 True 的就走 A 路线,否则就是 B 路线,真是,妙啊。
时候不早了,先卷到这。接下来都是硬茬,有的啃了。诸位,咱们青山不改,绿水长流,下期见。