一、初识装饰器:代码世界的"俄罗斯套娃"
在Python的魔法世界里,装饰器(Decorator)就像代码界的俄罗斯套娃,它允许我们在不修改原函数代码的情况下,为函数动态添加新功能。这种"开闭原则"的完美实践,让我们的代码既保持了简洁性,又获得了强大的扩展能力。
def simple_decorator(func):
def wrapper():
print("函数执行前")
func()
print("函数执行后")
return wrapper
@simple_decorator
def say_hello():
print("Hello World!")
say_hello()
当这段代码运行时,你会看到:
函数执行前
Hello World!
函数执行后
二、装饰器的四大实战场景
1. 性能监控器
import time
def timer(func):
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(f"{func.__name__} 执行耗时:{end - start:.4f}秒")
return result
return wrapper
@timer
def complex_calculation():
# 模拟复杂计算
time.sleep(1.5)
complex_calculation()
2. 权限守卫者
def login_required(func):
def wrapper(user, *args, **kwargs):
if not user.is_authenticated:
raise PermissionError("需要登录后才能访问")
return func(user, *args, **kwargs)
return wrapper
@login_required
def view_profile(user):
print(f"欢迎查看个人资料:{user.username}")
3. 缓存加速器
from functools import lru_cache
@lru_cache(maxsize=128)
def fibonacci(n):
if n < 2:
return n
return fibonacci(n-1) + fibonacci(n-2)
print(fibonacci(30)) # 速度提升立竿见影
4. 日志记录仪
def logger(func):
def wrapper(*args, **kwargs):
print(f"[日志] 开始执行:{func.__name__}")
result = func(*args, **kwargs)
print(f"[日志] 执行完成:{func.__name__}")
return result
return wrapper
三、装饰器的进阶技巧
1. 带参数的装饰器
def repeat(times):
def decorator(func):
def wrapper(*args, **kwargs):
for _ in range(times):
result = func(*args, **kwargs)
return result
return wrapper
return decorator
@repeat(3)
def alarm():
print("请注意!")
alarm() # 输出3次警告
2. 类装饰器
class CountCalls:
def __init__(self, func):
self.func = func
self.calls = 0
def __call__(self, *args, **kwargs):
self.calls += 1
print(f"第{self.calls}次调用")
return self.func(*args, **kwargs)
@CountCalls
def api_request():
# 模拟API调用
pass
api_request()
api_request()
四、装饰器的最佳实践
-
保持装饰器通用性:使用
*args和**kwargs接收任意参数 -
保留函数元信息:使用
@functools.wraps(func)装饰wrapper - 避免装饰器嵌套过深:超过3层的装饰器要考虑重构
- 合理处理异常:在wrapper中添加异常处理逻辑
- 注意执行顺序:装饰器的应用顺序是自下而上的
from functools import wraps
def proper_decorator(func):
@wraps(func) # 保持原函数信息
def wrapper(*args, **kwargs):
try:
print("装饰器前置操作")
return func(*args, **kwargs)
except Exception as e:
print(f"捕获异常:{str(e)}")
finally:
print("装饰器后置操作")
return wrapper
五、装饰器的妙用场景
- Flask路由注册:
@app.route('/') - Django权限控制:
@login_required - 单元测试标记:
@pytest.mark.skip - 类型检查:
@typechecked - 异步函数转换:
@asyncio.coroutine
# Flask路由示例
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return "欢迎来到Python装饰器世界!"
结语:装饰器的哲学
装饰器不仅是一种语法糖,更体现了Python"显式优于隐式"的设计哲学。它像一位代码化妆师,在不改变本质的前提下为函数增添魅力;又像一位代码建筑师,搭建起功能扩展的桥梁。掌握装饰器,你就掌握了Python进阶之路上的一把金钥匙。
下次当你看到@符号时,不妨会心一笑:这简单的符号背后,藏着Python开发者追求代码优雅的永恒追求。现在,就让我们用装饰器,为代码穿上优雅的外衣,让程序世界变得更加美好吧!
如果本文对你有帮助,欢迎点赞收藏!关于Python装饰器的更多深度技巧,我们下期再见~