欢迎访问我的博客首页。
装饰器
- [1. 函数装饰函数](#1. 函数装饰函数)
-
- [1.1 基础装饰器](#1.1 基础装饰器)
- [1.2 装饰器工厂](#1.2 装饰器工厂)
- [2. 函数装饰类](#2. 函数装饰类)
- [3. 类装饰函数](#3. 类装饰函数)
- [4. 类装饰类](#4. 类装饰类)
- [5. 参考](#5. 参考)
1. 函数装饰函数
用函数装饰函数的装饰器。
1.1 基础装饰器
下面定义一个名为 decorator 的装饰器。functools.wraps 用于还原函数名。
python
import functools
def 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 的例子。
python
@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 装饰器工厂
下面是带参数的装饰器及其用法。
python
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 wrapper
return decorator
@decorator_factor(param=2)
def test2():
return 'hello world2'
if __name__ == '__main__':
print(test2())
装饰器工厂用于控制被装饰函数的执行次数,以及统计被装饰函数的耗时等。
2. 函数装饰类
用函数装饰类的装饰器,以单例模式为例。
python
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. 类装饰函数
用类装饰函数的装饰器。
python
class Decorator:
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
param = args[0]
param += 1
return self.func(param)
@Decorator
def fac(param):
return param
if __name__ == '__main__':
print(fac(1))
装饰函数的类,可以预处理被装饰函数的参数。
4. 类装饰类
用类装饰类的装饰器,以单例模式为例。
python
class Singleton:
instance = None
def __init__(self, cls):
self.cls = cls
def __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。