### 装饰器的工作原理
装饰器就是能让你在一个函数执行前后去执行其他代码的函数或者类
下面通过代码来看一个简单的装饰器的实现过程
```python
# 定义一个装饰器
def a_decorator(f):
def wrapFunction():
print("在函数f执行前,输出文字")
f()
print("在函数f执行后,输出文字")
return wrapFunction
# 定义一个函数
def a_function():
print("hello!")
# 修饰函数
a_function = a_decorator(a_function)
# 调用函数
a_function()
# 输出结果
# 在函数f执行前,输出文字
# hello!
# 在函数f执行后,输出文字
```
以上就是一个调用装饰器的时候函数内部所做的操作,python中使用@来实现装饰过程,下面使用@来运行前面的代码:
```
# 调用装饰器,定义函数
@a_decorator
def a_function():
print("hello!")
# 调用函数
a_function()
# 输出结果
# 在函数f执行前,输出文字
# hello!
# 在函数f执行后,输出文字
```
### 使用@wraps接受一个函数来进行装饰
上面的代码让我们对装饰器的基本原理有了一个了解,但是这样做会出现一个问题
```
print(a_function.__name__)
# 输出
wrapFunction
```
明显可以看出输出的函数名并不是我们想要的a_function
python给我们提供了一个简单的函数funstools.wraps来解决问题
```
from functools import wraps
# 定义装饰器
def a_decorator(f):
@wraps(f)
def wrapFunction():
print("在函数f执行前,输出文字")
f()
print("在函数f执行后,输出文字")
return wrapFunction
# 使用装饰器
@a_decorator
def a_function():
print("hello!")
# 输出函数名字
print(a_function.__name__)
a_function
```
### 带参数的装饰器
使用带有参数的包裹函数将装饰器包裹起来,就可以创建一个带有参数的装饰器
```
from functools import wraps
# 定义装饰器
def other_decorator(x=1, y=2):
def a_decorator(func):
@wraps(func)
def wrapFunction(*args, **kwargs):
print("在函数f执行前,输出文字")
if x == 1:
print(x * y)
else:
print(x + y)
return func(*args, **kwargs)
return wrapFunction
return a_decorator
@other_decorator() # 这里的装饰器括号不能忘了
def a_function():
print("hello!")
# 调用函数
print(a_function())
在函数f执行前,输出文字
2
hello!
```
网友评论