装饰器是 Python
中比较重要的一个概念,它是基于装饰器模式实现的,装饰器模式是一种结构型设计模式,它允许向现有的一个对象添加新的功能,而又不改变其结构。
在 Python
中,装饰器是一个函数或者是一个类,它的功能是让其他函数或者类在不改变内部结构的情况下添加新的功能,通常用于切面需求,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景,它的返回值也是一个函数。
通常,我们会使用高阶函数来实现装饰器,可以接收函数作为参数的函数我们就称其为高阶函数。当然,也可以使用类来实现装饰器,那就是类装饰器。
1. 函数装饰器
下面是常见的函数装饰器的结构:
from functools import wraps
def decorator(func):
@wraps(func) # 将func函数的元信息拷贝到wrapper函数中
def wrapper(*args, **kwargs):
print('decorator!!!!')
# do everything # 在函数func执行前执行
return func(*args, **kwargs)
return wrapper
@decorator
def test():
'''一个不允许修改的函数哦!'''
# do something
return 'my test'
运行上面的test函数:
In [1]: test()
decorator!!!
Out [1]: 'my test'
使用 @
语法,将装饰器 decorator
装饰在函数 test
上面时,会把 test
作为一个参数传给 decorator
,返回新的函数 wrapper
,在装饰器内部的 wraps
用于把 func
的文档字符串以及函数名拷贝到内部函数 wrapper
上。此时,当我们调用 test
函数的时候,实际上调用的是 wrapper
函数。这样,在不修改函数 test
内部代码的情况下添加了我们想要添加的功能。
对于函数 test
的参数,在装饰器 decorator
中,通过参数打包的方式传给 func
。
2. 装饰器参数
某些时候,可能需要给装饰器传参数,那么需要再定义一层函数,使用 @
语法装饰函数时传给装饰器参数。
from functools import wraps
def outter(param):
def decorator(func):
@wraps(func) # 将func函数的元信息拷贝到wrapper函数中
def wrapper(*args, **kwargs):
print('装饰器参数: ', param)
print('decorator!!!!')
# do everything # 在函数func执行前执行
return func(*args, **kwargs)
return wrapper
return decorator
@outter('for test')
def test():
'''一个不允许修改的函数哦!'''
# do something
return 'my test'
3. 类装饰器
装饰器也可以是一个类,类装饰器主要依赖于 __call__
方法:
class Decorator(object):
def __init__(self, func):
self.__func = func
def __call__(self, *args, **kwargs):
# do something
return self._func(*args, **kwargs)
@Decorator
def test():
'''一个不允许修改的函数哦!'''
# do something
return 'my test'
4. 装饰器的顺序
一个函数如果被多个装饰器装饰,则按照先里后外的顺序装饰:
@decorator3
@decorator2
@decorator1
def test():
pass
上面的代码相当于:
func = decorator3(decorator2(decorator1(test)))