欢迎访问我的博客首页。
装饰器
- 1. 函数装饰函数
- 1.1 基础装饰器
- 1.2 装饰器工厂
- 2. 函数装饰类
- 3. 类装饰函数
- 4. 类装饰类
- 5. 参考
1. 函数装饰函数
用函数装饰函数的装饰器。
1.1 基础装饰器
下面定义一个名为 decorator 的装饰器。functools.wraps 用于还原函数名。
import functoolsdef decorator(func):@functools.wraps(func)def wrapper(*args, **kwargs):print('original func name:', func.__name__)return func(*args, **kwargs)return wrapper
下面是使用装饰器 decorator 装饰函数 test1_1 和 test1_2 的例子。
@decorator
def test1_1():return 'hello world1_1'def test1_2():return 'hello world1_2'test1_2 = decorator(test1_2)if __name__ == '__main__':print(test1_1())print()print(test1_2())
装饰函数的函数,可以预处理被装饰函数的参数。基于 python 的 web 应用程序的后端框架经常用这样的装饰器作为登录验证,比如 flask 框架。
1.2 装饰器工厂
下面是带参数的装饰器及其用法。
def decorator_factor(param=0):def decorator(func):@functools.wraps(func)def wrapper(*args, **kwargs):print('original func name:', func.__name__)print('param:', param)return func(*args, **kwargs)return wrapperreturn decorator@decorator_factor(param=2)
def test2():return 'hello world2'if __name__ == '__main__':print(test2())
装饰器工厂用于控制被装饰函数的执行次数,以及统计被装饰函数的耗时等。
2. 函数装饰类
用函数装饰类的装饰器,以单例模式为例。
def singleton(cls):instance = {}def create(*args, **kwargs):if cls not in instance:param = args[0]instance[cls] = cls(param + 1)return instance[cls]return create@singleton
class Example:def __init__(self, x):print('--构造函数, x=', x)def __del__(self):print('--析构函数')if __name__ == '__main__':a = Example(1)b = Example(1)print(id(a))print(id(b))
装饰类的函数,可以预处理被装饰类的构造函数的参数,也可以控制被装饰函数的对象的创建。
3. 类装饰函数
用类装饰函数的装饰器。
class Decorator:def __init__(self, func):self.func = funcdef __call__(self, *args, **kwargs):param = args[0]param += 1return self.func(param)@Decorator
def fac(param):return paramif __name__ == '__main__':print(fac(1))
装饰函数的类,可以预处理被装饰函数的参数。
4. 类装饰类
用类装饰类的装饰器,以单例模式为例。
class Singleton:instance = Nonedef __init__(self, cls):self.cls = clsdef __call__(self, *args, **kwargs):if not self.instance:self.instance = self.cls(*args, **kwargs)return self.instance@Singleton
class Example:def __init__(self):print('--构造函数')def __del__(self):print('--析构函数')if __name__ == '__main__':a = Example()b = Example()print(id(a))print(id(b))
装饰类的类,可以预处理被装饰类的构造函数的参数,也可以控制被装饰函数的对象的创建。
5. 参考
- 装饰器工厂,CSDN,2022。
- python 单例模式,CSDN,2023。
- 函数与类相互装饰,CSDN,2023。