最简装饰器
def deco(func):
def wrap(*args, **kwargs):
return func(*args, **kwargs)
return wrap
@deco
def foo(a, b):
return a ** b
原理
对比被装饰前后的 foo.__name__
和 foo.__doc__
from functools import wraps
def deco(func):
'''i am deco'''
@wraps(func) # 还原被装饰器修改的原函数属性
def wrap(*args, **kwargs):
'''i am wrap'''
return func(*args, **kwargs)
return wrap
简单过程
fn = deco(func)
foo = fn
foo(*args, **kwargs)
多个装饰器叠加调用的过程
@deco1
@deco2
@deco3
def foo(x, y):
return x ** y
# 过程拆解 1
fn3 = deco3(foo)
fn2 = deco2(fn3)
fn1 = deco1(fn2)
foo = fn1
foo(3, 4)
# 过程拆解 2
# 单行: deco1( deco2( deco3(foo) ) )(3, 2)
deco1(
deco2(
deco3(foo)
)
)(3, 4)
带参数的装饰器
def deco(n):
def wrap1(func):
def wrap2(*args, **kwargs):
return func(*args, **kwargs)
return wrap2
return wrap1
# 调用过程
wrap1 = deco(n)
wrap2 = wrap1(foo)
foo = wrap2
foo()
# 单行形式
check_result(30)(foo)(4, 8)
装饰器类和 call
class Deco:
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
return self.func(*args, **kwargs)
@Deco
def foo(x, y):
return x ** y
# 过程拆解
fn = Deco(foo)
foo = fn
foo(12, 34)