张芷铭的个人博客

装饰器是 Python 的语法糖,本质是函数包装:@decorator 等价于 func = decorator(func)

装饰器基础

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
def my_decorator(func):
    def wrapper(*args, **kwargs):
        print("调用前")
        result = func(*args, **kwargs)
        print("调用后")
        return result
    return wrapper

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

# 等价于
say_hello = my_decorator(say_hello)

带参数的装饰器

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
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():
    print("Hi!")

类装饰器

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
class CountCalls:
    def __init__(self, func):
        self.func = func
        self.count = 0

    def __call__(self, *args, **kwargs):
        self.count += 1
        return self.func(*args, **kwargs)

@CountCalls
def my_func():
    pass

常见问题

方法装饰器缩进错误

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# ❌ 错误:装饰器不应缩进
class MyClass:
    @decorator
    def method(self):
        pass

# ❌ 错误:装饰器使用 self
@track_cuda_memory(self.device)  # self 未定义
def method(self):
    pass

# ✅ 正确:装饰器在方法内部调用或使用闭包
def method(self):
    @track_cuda_memory(self.device)
    def inner():
        pass
    return inner()

常用内置装饰器

装饰器用途
@staticmethod静态方法
@classmethod类方法
@property属性访问器
@functools.wraps保留原函数元信息

Comments