1 最基础的装饰器
def decorator(f):
def inner():
print('before')
res = f()
print('after')
return res
return inner
@decorator
def task1():
print('执行task1')
return 'complete'
task1()
"""
before
执行task1
after
"""
2 带参数的装饰器
def say(sex):
def wrapper(f):
def inner():
print('start')
f(sex)
print('stop')
return inner
return wrapper
@say('man')
def boy(sex):
if sex == 'man':
print('搬砖。。。。')
else:
print('躺平。。。。')
@say('women')
def girl(sex):
if sex == 'man':
print('搬砖。。。。')
else:
print('躺平。。。。')
boy()
girl()
先调用say(‘man’) 返回wrapper函数,然后使用wrapper函数装饰目标函数,比如wrapper(boy)()
带参数装饰器的应用场景:
def route(url):
def deractor(func):
url_map[url] = func
return func
return deractor
@route('/index')
def index():
pass
@route('login')
def login():
pass
print(url_map)
# {'/index': <function index at 0x000002B23604BA60>, 'login': <function login at 0x000002B23604BAF0>}
3 被装饰函数的函数名
def decorator(f):
def inner():
print('before')
res = f()
print('after')
return res
return inner
@decorator
def task1():
print('执行task1')
@decorator
def task2():
print('执行task2')
print(task1.__name__) # inner
print(task2.__name__) # inner
3.1 修改方式一:
def decorator(f):
def inner(*args, **kwargs):
print('before')
res = f(*args, **kwargs)
print('after')
return res
inner.__name__ = f.__name__ # 直接修改inner的函数名字为被装饰的函数名即可
return inner
@decorator
def task1():
print('执行task1')
@decorator
def task2():
print('执行task2')
print(task1.__name__)
print(task2.__name__)
3.2 修改方式二:
from functools import wraps
def decorator(f):
@wraps(f)
def inner(*args, **kwargs):
print('before')
res = f(*args, **kwargs)
print('after')
return res
return inner
@decorator
def task1():
print('执行task1')
@decorator
def task2():
print('执行task2')
print(task1.__name__)
print(task2.__name__)
4 简单的类装饰器
def wrap(obj):
obj.name = 'python'
return obj
@wrap
class Foo:
def __init__(self):
pass
print(Foo.name) # python
@wrap 等价于 wrap(Foo)