🎨 Python装饰器完全指南:从入门到精通
Python装饰器是Python中最强大且优雅的特性之一,它允许你在不修改原函数代码的情况下,给函数添加额外的功能。本文将从基础概念到高级应用,带你全面掌握装饰器。
一、什么是装饰器?
装饰器本质上是一个高阶函数,它接收一个函数作为参数,并返回一个新的函数。装饰器的语法使用 @ 符号,放在函数定义之前。
# 一个简单的装饰器示例
def my_decorator(func):
def wrapper():
print("函数执行前")
func()
print("函数执行后")
return wrapper
@my_decorator
def say_hello():
print("Hello!")
say_hello()
# 输出:
# 函数执行前
# Hello!
# 函数执行后
二、带参数的装饰器
实际应用中,被装饰的函数通常带有参数。我们需要让装饰器能够处理任意参数:
def decorator_with_args(func):
def wrapper(*args, **kwargs):
print(f"调用函数: {func.__name__}")
print(f"位置参数: {args}")
print(f"关键字参数: {kwargs}")
result = func(*args, **kwargs)
print(f"函数返回值: {result}")
return result
return wrapper
@decorator_with_args
def add(a, b):
return a + b
add(3, 5)
# 输出函数名、参数和返回值
三、装饰器本身带参数
有时候我们希望装饰器本身也能接收参数,这时需要嵌套三层函数:
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(times=3)
def greet(name):
print(f"Hello, {name}!")
greet("Alice")
# 会打印三次 "Hello, Alice!"
四、类装饰器
除了函数装饰器,Python还支持使用类作为装饰器:
class CountCalls:
def __init__(self, func):
self.func = func
self.count = 0
def __call__(self, *args, **kwargs):
self.count += 1
print(f"{self.func.__name__} 被调用了 {self.count} 次")
return self.func(*args, **kwargs)
@CountCalls
def say_hi():
print("Hi!")
say_hi() # 被调用了 1 次
say_hi() # 被调用了 2 次
五、常用内置装饰器
1. @property - 将方法转为属性
class Circle:
def __init__(self, radius):
self._radius = radius
@property
def area(self):
return 3.14159 * self._radius ** 2
@property
def radius(self):
return self._radius
@radius.setter
def radius(self, value):
if value < 0:
raise ValueError("半径不能为负数")
self._radius = value
c = Circle(5)
print(c.area) # 像访问属性一样访问方法
print(c.radius) # 获取半径
c.radius = 10 # 设置半径
2. @staticmethod 和 @classmethod
class MyClass:
class_var = "类变量"
@staticmethod
def static_method():
print("静态方法,不需要self或cls")
@classmethod
def class_method(cls):
print(f"类方法可以访问: {cls.class_var}")
MyClass.static_method() # 直接通过类调用
MyClass.class_method()
3. @functools.wraps - 保留原函数信息
from functools import wraps
def proper_decorator(func):
@wraps(func) # 保留原函数的元数据
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return wrapper
@proper_decorator
def example():
"""这是example的文档"""
pass
print(example.__name__) # 输出: example (不是wrapper)
print(example.__doc__) # 输出: 这是example的文档
六、实际应用案例
1. 计时装饰器
import time
from functools import wraps
def timer(func):
@wraps(func)
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
elapsed = time.time() - start
print(f"{func.__name__} 执行时间: {elapsed:.4f}秒")
return result
return wrapper
@timer
def slow_function():
time.sleep(1)
return "Done"
slow_function()
2. 缓存装饰器 (Memoization)
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(100)) # 瞬间完成
七、多个装饰器叠加
装饰器可以叠加使用,执行顺序是从下往上:
@decorator_a
@decorator_b
@decorator_c
def my_func():
pass
# 等价于:
# my_func = decorator_a(decorator_b(decorator_c(my_func)))
八、总结
装饰器是Python中实现面向切面编程(AOP)的利器,能让你的代码更加简洁、可复用。掌握装饰器,是成为Python高级开发者的必经之路!
关键要点:
- 基础语法:
@decorator放在函数定义前 - 带参数的装饰器:需要三层嵌套函数
- 类装饰器:实现
__call__方法 - 常用内置:@property, @staticmethod, @classmethod, @wraps
- 应用场景:日志记录、性能计时、权限检查、缓存等
本文内容由AI生成,仅供学习参考。

浙公网安备 33010602011771号