[关闭]
@EggGump 2022-05-26T14:04:51.000000Z 字数 1698 阅读 212

装饰器

python


本质

装饰器其实就是一个函数,不过它的传入参数也是一个函数,装饰器的目的是用来增强函数功能的.

1. 最简单函数

现在假如我们有一个输出一句诗的函数

  1. def poem():
  2. print("千呼万唤shi出来")
  3. poem()

我们想,在函数执行开始和执行结束得有个标记,不然我们也不知道他吟诗结没结束,如果直接加在函数上就会变成这样:

  1. def poem():
  2. print('我要开始了!!')
  3. print("千呼万唤shi出来")
  4. print("我结束了!!")
  5. poem()

这会使使得poem()函数不够纯粹,吟诗的只管吟诗,没必要管开始结束;此外就是麻烦,假如还有唱戏函数,小品函数,我不得每个都加?装饰器就管这个作用.
比如现在要给一个函数增加一个基本的开始和结束提示,我们可以写一个实现相应功能的装饰器:

  1. def start_end(func):
  2. def stage():
  3. print("我开始了:")
  4. func()
  5. print("我结束了!!!")
  6. return stage

再在原来的吟诗函数上添加上我们定义的装饰器:

  1. @start_end
  2. def poem():
  3. print("千呼万唤shi出来")
  4. poem()

其实当我们调用poem()函数时,程序会把poem这个函数传给装饰器,再运行stage()函数里面的内容,这时会输出:

  1. 我开始了:
  2. 千呼万唤shi出来
  3. 我结束了!!!

2. 有返回值的函数

前面的函数没有返回值,假如现在有返回值呢,比如诗人吟诗后会把名字告诉工作人员,我们将它返回,程序变为:

  1. @start_end
  2. def poem():
  3. print("千呼万唤shi出来")
  4. return '我是李白'
  5. print(poem())

运行结果

  1. 我开始了:
  2. 千呼万唤shi出来
  3. 我结束了!!!
  4. None

显然这不是我们想要的,因为装饰器里没有实现返回值功能,所以我们无法获得poem()函数的返回值,这时我们对装饰器作修改:

  1. def start_end(func):
  2. def stage():
  3. print("我开始了:")
  4. result = func()
  5. print("我结束了!!!")
  6. return result
  7. return stage

即在stage()函数里获得func函数的返回值,再在stage函数里返回即可,此时运行结果:

  1. 我开始了:
  2. 千呼万唤shi出来
  3. 我结束了!!!
  4. 我是李白

3. 有参函数

假如现在这个诗人会吟很多诗,他要把想吟的诗作为参数传给poem()该怎么办呢?
假如现在这个诗人想吟孔雀东南飞了,我们改写下poem函数:

  1. @start_end
  2. def poem(str):
  3. print(str)
  4. return '我是李白'
  5. bird = '孔雀东南飞,自挂东南枝'
  6. print(poem(bird))

运行结果:

  1. Traceback (most recent call last):
  2. File "/home/hb/software/ryu/Deco.py", line 16, in <module>
  3. print(poem(bird))
  4. TypeError: stage() takes 0 positional arguments but 1 was given

出错了,因为装饰器不支持参数啊,所以我们还要改进下装饰器:

  1. def start_end(func):
  2. def stage(*args):
  3. print("我开始了:")
  4. result = func(*args)
  5. print("我结束了!!!")
  6. return result
  7. return stage

只要在stage()函数里添加*args,再将它传给func()函数即可,相当于上台前有个稿子是诗人准备的,稿子是什么我不管,把正原想交给诗人即可
再次运行:

  1. 我开始了:
  2. 孔雀东南飞,自挂东南枝
  3. 我结束了!!!
  4. 我是李白

最后整体代码:

  1. def start_end(func):
  2. def stage(*args):
  3. print("我开始了:")
  4. result = func(*args)
  5. print("我结束了!!!")
  6. return result
  7. return stage
  8. @start_end
  9. def poem(str):
  10. print(str)
  11. return '我是李白'
  12. bird = '孔雀东南飞,自挂东南枝'
  13. print(poem(bird))
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注