Python 之装饰器

时间:2023-03-09 09:17:01
Python 之装饰器

Python 的装饰器可谓是提高开发效率的一大利器。然而初学装饰器的时候感觉很难理解,因为除了 Python 之外没听说哪个语言有这种东西。

而且网上看的很多解释看似容易理解,但只能很快理解了装饰器能用来干嘛,看完了还是有点懵。


在我看来 Python 装饰器的本质就是:利用 Python 能够将函数作为参数、返回值,且支持函数嵌套的特性。新建一个函数作为装饰器来给已有的函数添加功能。

Talk is Cheap,直接来看代码:

def a_good_decorater(a_func):
#装饰器函数
def wrap_a_func():
print("Hit You")
a_func()
print("Hit You Again")
return wrap_a_func @a_good_decorater#此处为 Python 语法糖 可以方便地装饰函数
def pri():
print("HaHaHa, This is my first decorater") pri() >>>hit You
>>>HaHaHa, This is my first decorater
>>>hit You Again

装饰器的流程如下:

1.新建一个函数,这里称为装饰器。

2.在函数中再次建立一个函数,这里把它称为装饰函数,用来给函数添加功能。这么做的意义是能让函数经过装饰后仍然是一个函数。如果不这么做,那么就会在装饰过程中就执行函数了,还想达到期望的效果就需要在每次条用函数前都用装饰器来装饰函数,大大减少了开发效率。

3.装饰器的返回值为装饰函数。

4.将函数修改为装饰函数装饰过后的函数。

以此处代码为例,这么做完以后相当于在函数上下都加了一行 print 命令。

所以,装饰器的作用就是以同一种方式修改函数,适用于大量函数都需要添加同一功能的情况。


到这里,已经能够使用装饰器来装饰函数了。

但是,有一个问题。

由于装饰器中已经返回了装饰函数,所以相当于现有的函数已经被修改成装饰函数了,例如函数名就会是 wrap_a_func。看起来没什么问题,但是当需要用到函数属性的操作时就会出错。然而贴心的 Python 也为我们考虑到了。通过 functools.wraps 对装饰函数再次装饰,就能保留原函数的名字等。

from functools import wraps

def a_good_decorater(a_func):
@wraps(a_func)
def wrap_a_func():
print("hit You")
a_func()
print("hit You Again")
return wrap_a_func @a_good_decorater
def pri():
print("HaHaHa, This is my first decorater") pri()
print(pri.__name__) >>>hit You
>>>HaHaHa, This is my first decorater
>>>hit You Again
>>>pri