Python 装饰器(Decorator)是一种强大且灵活的特性,允许开发者在不修改原函数代码的情况下,为其动态地添加额外功能。装饰器广泛应用于 日志记录、权限控制、性能优化、缓存机制 等场景。
本文将从 装饰器的底层原理、高级用法、性能优化、常见陷阱及源码分析 等多个角度,深度解析 Python 装饰器的强大之处。
装饰器本质上是 高阶函数(Higher-order Function),即 接受一个函数作为输入,并返回一个新的函数。Python 的函数是一等公民,因此可以像变量一样传递。
def simple_decorator(func):
def wrapper(*args, **kwargs):
print("函数执行前")
result = func(*args, **kwargs)
print("函数执行后")
return result
return wrapper
@simple_decorator
def greet():
print("Hello, Python!")
greet()
输出:
函数执行前
Hello, Python!
函数执行后
@wraps
解决装饰器覆盖原函数元信息的问题from functools import wraps
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return wrapper
@wraps
作用:保留 func.__name__
、func.__doc__
等元信息。
def repeat(n):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
for _ in range(n):
func(*args, **kwargs)
return wrapper
return decorator
@repeat(3)
def say_hello():
print("Hello!")
say_hello()
class Timer:
def __init__(self, func):
self.func = func
wraps(func)(self)
def __call__(self, *args, **kwargs):
import time
start_time = time.time()
result = self.func(*args, **kwargs)
end_time = time.time()
print(f"{self.func.__name__} 运行时间: {end_time - start_time:.4f} 秒")
return result
@Timer
def example():
import time
time.sleep(2)
print("执行完成")
example()
装饰器按照从内到外的顺序执行。
def uppercase(func):
@wraps(func)
def wrapper():
return func().upper()
return wrapper
def exclamation(func):
@wraps(func)
def wrapper():
return func() + "!!!"
return wrapper
@exclamation
@uppercase
def greet():
return "hello"
print(greet()) # 输出: HELLO!!!
import logging
def log(func):
@wraps(func)
def wrapper(*args, **kwargs):
logging.info(f"调用 {func.__name__},参数: {args} {kwargs}")
return func(*args, **kwargs)
return wrapper
@log
def add(a, b):
return a + b
def requires_admin(func):
@wraps(func)
def wrapper(user, *args, **kwargs):
if not user.get("is_admin"):
print("权限不足!")
return
return func(user, *args, **kwargs)
return wrapper
@requires_admin
def delete_user(user, username):
print(f"删除用户 {username}")
装饰器引入了额外的函数调用层,因此可能会对性能产生影响。
lru_cache
进行缓存优化from functools import lru_cache
@lru_cache(maxsize=128)
def fib(n):
if n < 2:
return n
return fib(n-1) + fib(n-2)
lru_cache
通过缓存函数结果,避免重复计算,提高性能。
在高性能需求的应用中,尽量减少嵌套装饰器的层数,避免额外的函数调用开销。
装饰器 | 作用 |
---|---|
@staticmethod |
定义静态方法 |
@classmethod |
定义类方法 |
@property |
定义只读属性 |
@lru_cache |
提高性能,缓存函数结果 |
@contextmanager |
创建上下文管理器 |
示例:
class Example:
@staticmethod
def static_method():
print("静态方法")
@classmethod
def class_method(cls):
print("类方法")
@property
def prop(self):
return "只读属性"
Python 装饰器是 代码复用、逻辑抽象 的重要工具,掌握装饰器的用法能够大幅提高代码的可维护性。
总结要点:
希望本文能帮助你深入理解 Python 装饰器的高级用法,如果觉得有帮助,欢迎点赞、评论和收藏!