@EggGump
2022-05-26T14:04:51.000000Z
字数 1698
阅读 212
python
装饰器其实就是一个函数,不过它的传入参数也是一个函数,装饰器的目的是用来增强函数功能的.
现在假如我们有一个输出一句诗的函数
def poem():
print("千呼万唤shi出来")
poem()
我们想,在函数执行开始和执行结束得有个标记,不然我们也不知道他吟诗结没结束,如果直接加在函数上就会变成这样:
def poem():
print('我要开始了!!')
print("千呼万唤shi出来")
print("我结束了!!")
poem()
这会使使得poem()函数不够纯粹,吟诗的只管吟诗,没必要管开始结束;此外就是麻烦,假如还有唱戏函数,小品函数,我不得每个都加?装饰器就管这个作用.
比如现在要给一个函数增加一个基本的开始和结束提示,我们可以写一个实现相应功能的装饰器:
def start_end(func):
def stage():
print("我开始了:")
func()
print("我结束了!!!")
return stage
再在原来的吟诗函数上添加上我们定义的装饰器:
@start_end
def poem():
print("千呼万唤shi出来")
poem()
其实当我们调用poem()函数时,程序会把poem这个函数传给装饰器,再运行stage()函数里面的内容,这时会输出:
我开始了:
千呼万唤shi出来
我结束了!!!
前面的函数没有返回值,假如现在有返回值呢,比如诗人吟诗后会把名字告诉工作人员,我们将它返回,程序变为:
@start_end
def poem():
print("千呼万唤shi出来")
return '我是李白'
print(poem())
运行结果
我开始了:
千呼万唤shi出来
我结束了!!!
None
显然这不是我们想要的,因为装饰器里没有实现返回值功能,所以我们无法获得poem()函数的返回值,这时我们对装饰器作修改:
def start_end(func):
def stage():
print("我开始了:")
result = func()
print("我结束了!!!")
return result
return stage
即在stage()函数里获得func函数的返回值,再在stage函数里返回即可,此时运行结果:
我开始了:
千呼万唤shi出来
我结束了!!!
我是李白
假如现在这个诗人会吟很多诗,他要把想吟的诗作为参数传给poem()该怎么办呢?
假如现在这个诗人想吟孔雀东南飞了,我们改写下poem函数:
@start_end
def poem(str):
print(str)
return '我是李白'
bird = '孔雀东南飞,自挂东南枝'
print(poem(bird))
运行结果:
Traceback (most recent call last):
File "/home/hb/software/ryu/Deco.py", line 16, in <module>
print(poem(bird))
TypeError: stage() takes 0 positional arguments but 1 was given
出错了,因为装饰器不支持参数啊,所以我们还要改进下装饰器:
def start_end(func):
def stage(*args):
print("我开始了:")
result = func(*args)
print("我结束了!!!")
return result
return stage
只要在stage()函数里添加*args,再将它传给func()函数即可,相当于上台前有个稿子是诗人准备的,稿子是什么我不管,把正原想交给诗人即可
再次运行:
我开始了:
孔雀东南飞,自挂东南枝
我结束了!!!
我是李白
最后整体代码:
def start_end(func):
def stage(*args):
print("我开始了:")
result = func(*args)
print("我结束了!!!")
return result
return stage
@start_end
def poem(str):
print(str)
return '我是李白'
bird = '孔雀东南飞,自挂东南枝'
print(poem(bird))