python自动化测试中使用装饰器
·
以下是 Python 中装饰器的高级用法总结,结合了多个实际应用场景和技术实现:
1. 带参数的装饰器
通过装饰器工厂模式动态生成装饰器,实现参数化功能扩展。例如,控制函数重复执行次数或添加条件判断逻辑。
def repeat(n): # 装饰器工厂
def decorator(func): # 实际装饰器
def wrapper(*args, **kwargs):
for _ in range(n):
result = func(*args, **kwargs)
return result
return wrapper
return decorator
@repeat(3) # 调用装饰器工厂生成装饰器
def greet(name):
print(f"Hello, {name}!")
greet("Alice") # 输出三次 "Hello, Alice!"
2. 类装饰器
使用类实现装饰器,通过 __init__ 和 __call__ 方法管理状态,支持更复杂的逻辑封装。
class Logger:
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
print(f"Calling {self.func.__name__}")
return self.func(*args, **kwargs)
@Logger
def add(a, b):
return a + b
print(add(2, 3)) # 输出日志并返回5
3. 多层装饰器
多个装饰器叠加时,执行顺序由内到外(从下往上),需注意逻辑顺序对结果的影响。
def bold(func):
def wrapper():
return f"<b>{func()}</b>"
return wrapper
def italic(func):
def wrapper():
return f"<i>{func()}</i>"
return wrapper
@bold
@italic
def say_hi():
return "Hi"
print(say_hi()) # 输出 "<b><i>Hi</i></b>"
4. 装饰器保留元数据
使用 functools.wraps 保留原函数的名称、文档等元信息,避免调试时信息丢失。
from functools import wraps
def log_decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
print(f"{func.__name__} is called")
return func(*args, **kwargs)
return wrapper
@log_decorator
def example():
"""示例函数"""
pass
print(example.__name__) # 输出 "example"
5. 动态装饰器
运行时根据条件动态选择装饰行为,例如根据环境切换调试模式。
def debug_decorator(debug=True):
def decorator(func):
def wrapper(*args, **kwargs):
if debug:
print("Debug mode: logging inputs")
return func(*args, **kwargs)
return wrapper
return decorator
@debug_decorator(debug=True)
def calculate(a, b):
return a * b
calculate(3, 4) # 输出调试信息
引用:[39]
6. 装饰器实现缓存
利用 functools.lru_cache 或自定义装饰器缓存函数结果,提升重复计算性能。
from functools import lru_cache
@lru_cache(maxsize=None)
def fibonacci(n):
if n < 2:
return n
return fibonacci(n-1) + fibonacci(n-2)
print(fibonacci(10)) # 快速计算斐波那契数
7. 装饰器模式与面向切面编程(AOP)
通过装饰器分离核心逻辑与横切关注点(如日志、权限校验)。
def admin_required(func):
def wrapper(user, *args, **kwargs):
if not user.is_admin:
raise PermissionError("Admin required")
return func(user, *args, **kwargs)
return wrapper
@admin_required
def delete_user(user):
print(f"User {user.name} deleted")
# 调用时自动校验权限
8. 装饰器在框架中的应用
如 Flask 的路由装饰器、Django 的登录校验装饰器。
from flask import Flask
app = Flask(__name__)
@app.route("/") # 路由装饰器
def home():
return "Welcome!"
引用:[25]
9.在class类内使用装饰器
import logging
import functools
# 将装饰器移到类外,作为普通函数
def log_function_call(func):
@functools.wraps(func)
def wrapper(self, *args, **kwargs):
self.logger.info(f'外部-a={self.a}')
self.logger.info(f"Calling function {func.__name__} with args: {args}, kwargs: {kwargs}")
try:
result = func(self, *args, **kwargs)
self.logger.info(f"Function {func.__name__} returned: {result}")
self.logger.info(f'内部-a={self.a}')
return result
except Exception as e:
self.logger.error(f"Function {func.__name__} raised an error: {e}")
raise
return wrapper
def two(self):
print(f'two--{self.a}')
class do_decorator:
def __init__(self):
logging.basicConfig(level=logging.INFO)
self.logger = logging.getLogger(__name__)
self.a='a'
@log_function_call # 直接应用外部装饰器
def api_endpoint(self, url):
self.logger.info(f"Testing endpoint at {url}")
def do_one(self):
two(self)
self.api_endpoint("https://example.com/api")
if __name__ == '__main__':
one = do_decorator()
one.do_one()
高级场景总结表
| 场景 | 技术点 | 引用来源 |
|---|---|---|
| 动态参数控制 | 装饰器工厂模式 | [21] |
| 类封装装饰逻辑 | 类装饰器 | [3] |
| 多层装饰器顺序 | 装饰器堆叠执行顺序 | [13] |
| 元数据保留 | functools.wraps | [4] |
| 动态切换行为 | 条件化装饰器 | [39] |
| 缓存优化 | lru_cache 或自定义 | [4] |
注意事项
- 避免过度装饰:嵌套过多装饰器可能降低代码可读性。
- 调试工具支持:使用
inspect模块检查装饰后的函数签名。 - 性能影响:复杂装饰器可能引入额外开销,需权衡功能与性能。
如需进一步了解具体实现细节,可参考 [11] 中关于装饰器与设计模式的对比分析,或 [16] 中关于装饰器性能优化的讨论。
更多推荐



所有评论(0)