1. 类装饰器(都不带参数)
class ClassDeco:
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
print(f'Running {self.func.__name__}')
self.func()
print(f'End {self.func.__name__}')
@ClassDeco # 等价于 foo = ClassDeco(foo)
def foo():
print('do something')
# call foo()
# OUT:
# Running foo
# do something
# End foo
2. 类装饰器带参数
class ClassDeco:
def __init__(self, x, y):
self.x = x
self.y = y
def __call__(self, func, *args, **kwargs):
print(f'Running {func.__name__}')
print(f'Using x + y = {self.x + self.y}')
return func
@ClassDeco(1, 2) # 等价于 foo = ClassDeco(1, 2)(foo)
def foo():
print('do something')
# call foo()
# OUT:
# Running bar1
# Using x + y = 3
# do something
3. 类装饰器不带参数,被包装对象带参数
class ClassDeco:
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
print(f'Running {self.func.__name__}')
self.func(*args, **kwargs)
print(f'End {self.func.__name__}')
@ClassDeco # 等价于foo = ClassDeco(foo)
def foo(a, b):
print('do something')
print(f'return a + b = {a + b}')
# foo(1, 2)
# OUT:
# Running foo
# do something
# return a + b = 3
# End foo
4. 类装饰器带参数且被装饰对象也带参数
from functools import wraps
class ClassDeco:
def __init__(self, x, y):
self.x = x
self.y = y
def __call__(self, func, *args, **kwargs):
print(f'Using x + y = {self.x + self.y}')
@wraps(func)
def wrapper(*args, **kwargs):
func(*args, **kwargs)
print(f'Ending {func.__name__}')
return wrapper
@ClassDeco(1, 2) # 等价于 foo = ClassDeco(1, 2)(foo)
def foo(a, b):
print('do something')
print(f'return a + b = {a + b}')
# call foo(3, 4)
# OUT:
# Using x + y = 3
# do something
# return a + b = 7
# Ending foo
if __name__ == '__main__':
foo(3, 4)
5. 参考
理解Python类装饰器__call__