全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-19 10 分钟 ✍️ juanwangdev

Python 函数装饰器原理

装饰器是修改函数行为的语法工具,本质是函数替换机制。

装饰器本质

Python
@decorator
def func():
    pass

# 等价于
def func():
    pass
func = decorator(func)

无参数装饰器

Python
def my_decorator(func):
    def wrapper():
        print("调用前")
        func()
        print("调用后")
    return wrapper

@my_decorator
def say_hello():
    print("Hello")

say_hello()
# 输出:
# 调用前
# Hello
# 调用后

带参数的函数

Python
def my_decorator(func):
    def wrapper(*args, **kwargs):
        print(f"参数: {args}, {kwargs}")
        result = func(*args, **kwargs)
        print(f"结果: {result}")
        return result
    return wrapper

@my_decorator
def add(a, b):
    return a + b

print(add(3, 5))
# 输出:
# 参数: (3, 5), {}
# 结果: 8
# 8

装饰器带参数

Python
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 greet(name):
    print(f"Hello, {name}")

greet("Alice")
# 输出3次:
# Hello, Alice
# Hello, Alice
# Hello, Alice

装饰器调用流程

Python
@repeat(3)
def greet(name):
    pass

解析步骤:
1. repeat(3) 返回 decorator 函数
2. decorator(greet) 返回 wrapper 函数
3. greet = wrapper(函数替换)

保持函数元信息

Python
from functools import wraps

def my_decorator(func):
    @wraps(func)  # 保持原函数的元信息
    def wrapper(*args, **kwargs):
        return func(*args, **kwargs)
    return wrapper

@my_decorator
def example():
    "示例函数"
    pass

print(example.__name__)  # example(而非 wrapper)
print(example.__doc__)   # 示例函数

类作为装饰器

Python
class CountCalls:
    def __init__(self, func):
        self.func = func
        self.count = 0

    def __call__(self, *args, **kwargs):
        self.count += 1
        print(f"调用次数: {self.count}")
        return self.func(*args, **kwargs)

@CountCalls
def say_hello():
    print("Hello")

say_hello()  # 调用次数: 1
say_hello()  # 调用次数: 2

多个装饰器叠加

Python
@decorator1
@decorator2
def func():
    pass

# 等价于
func = decorator1(decorator2(func))

# 执行顺序: decorator2 -> decorator1(从内到外)

常用装饰器示例

text
import time
from functools import wraps

# 计时装饰器
def timer(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        print(f"{func.__name__} 耗时 {time.time() - start:.4f}s")
        return result
    return wrapper

# 日志装饰器
def logger(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        print(f"调用 {func.__name__}")
        return func(*args, **kwargs)
    return wrapper

@timer
@logger
def process():
    time.sleep(1)

process()
# 输出:
# 调用 process
# process 耗时 1.00xxs

要点总结

  • 装饰器本质是 func = decorator(func) 的函数替换
  • 无参数装饰器返回包装函数
  • 带参数装饰器返回装饰器函数,再返回包装函数
  • 使用 @wraps 保持原函数元信息
  • 类装饰器通过 __call__ 实现调用
  • 多装饰器叠加从内到外执行
  • 装饰器用于日志、计时、权限、缓存等场景

📝 发现内容有误?点击此处直接编辑

← 上一篇 Python 函数作为对象
下一篇 → Python 闭包函数
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库