Python命名空间的本质 - windlaughing - 博客园
python 多层装饰器加载和执行顺序 - 萤huo虫 - 博客园
1、def decorator(func):
def wrapper(*args, **kwargs):
print('123')
return func(*args, **kwargs)
return wrapper
@decorator
def say_hello():
print('同学你好')
say_hello()
123
同学你好
2、带参数(多一层)
def info(value):
def decorator(func):
def wrapper(*args, **kwargs):
print(value)
return func(*args, **kwargs)
return wrapper
return decorator
@info('456')
def say_hello():
print('同学你好')
say_hello()
456
同学你好
3、 @wraps(func)
from functools import wraps
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
"""doc of wrapper"""
print('123')
return func(*args, **kwargs)
return wrapper
@decorator
def say_hello():
"""doc of say hello"""
print('同学你好')
print(say_hello.__name__)
print(say_hello.__doc__)
say_hello
doc of say hello
6、多层
加载自下而上, 执行自上而下
# an example of python decorator
def deco1(func):
print(1)
def wrapper1():
print(2)
func()
print(3)
print(4)
return wrapper1
def deco2(func):
print(5)
def wrapper2():
print(6)
func()
print(7)
print(8)
return wrapper2
@deco1
@deco2
def foo():
print('foo')
if __name__ == '__main__':
foo()
5
8
1
4
2
6
foo
7
3
类装饰器
class Decorator:
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
print('123')
return self.func(*args, **kwargs)
@Decorator
def say_hello():
print('同学你好')
say_hello()
# 被装饰函数重新定义 import functools # 使用自定义装饰器会改变被装饰的函数的函数名,解决方法: # 第一种 import functools @functoool.wraps(func) # 第二种 cell_fun.__name__ = func.__name__ def set_fun(func): @functools.wraps(func) def cell_fun(): print('cell_fun') # cell_fun.__name__ = func.__name__ return cell_fun @set_fun def a(): print('a run') print(a.__name__)