@EggGump
2022-05-26T06:04:51.000000Z
字数 1698
阅读 375
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_enddef poem():print("千呼万唤shi出来")poem()
其实当我们调用poem()函数时,程序会把poem这个函数传给装饰器,再运行stage()函数里面的内容,这时会输出:
我开始了:千呼万唤shi出来我结束了!!!
前面的函数没有返回值,假如现在有返回值呢,比如诗人吟诗后会把名字告诉工作人员,我们将它返回,程序变为:
@start_enddef poem():print("千呼万唤shi出来")return '我是李白'print(poem())
运行结果
我开始了:千呼万唤shi出来我结束了!!!None
显然这不是我们想要的,因为装饰器里没有实现返回值功能,所以我们无法获得poem()函数的返回值,这时我们对装饰器作修改:
def start_end(func):def stage():print("我开始了:")result = func()print("我结束了!!!")return resultreturn stage
即在stage()函数里获得func函数的返回值,再在stage函数里返回即可,此时运行结果:
我开始了:千呼万唤shi出来我结束了!!!我是李白
假如现在这个诗人会吟很多诗,他要把想吟的诗作为参数传给poem()该怎么办呢?
假如现在这个诗人想吟孔雀东南飞了,我们改写下poem函数:
@start_enddef 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 resultreturn stage
只要在stage()函数里添加*args,再将它传给func()函数即可,相当于上台前有个稿子是诗人准备的,稿子是什么我不管,把正原想交给诗人即可
再次运行:
我开始了:孔雀东南飞,自挂东南枝我结束了!!!我是李白
最后整体代码:
def start_end(func):def stage(*args):print("我开始了:")result = func(*args)print("我结束了!!!")return resultreturn stage@start_enddef poem(str):print(str)return '我是李白'bird = '孔雀东南飞,自挂东南枝'print(poem(bird))