心得:func看做一个函数形参变量,然后定义wrapper函数对func进行装饰后返回func().在调用debug函数时func函数具体化,比如叫func1,wrapper函数的定义中的func也具体化为func1,返回wrapper,这个wrapper是对前面的wrapper函数的具体化的实例,其func已经实例化为func1.
将 @debug 放在say_hello() 前面,相当于在原say_hello函数的定义后面执行了
say_hello = debug(say_hello)
由于debug()是一个装饰器,返回了wrapper函数,所以原来的say_hello()依然存在,只是现在同名的now变量指向了新的函数,于是调用say_hello()将执行新的函数,即在debug()函数中返回的wrapper()函数。
def debug(func): #2
def wrapper(): #3,8
print('[DEBUG]: enter {}()'.format(func.__name__)) #9
return func() #10,13
return wrapper #4
@debug #1,5,11
def say_hello():
print('hello!') #12
"""
[DEBUG]: enter say_hello()
hello!
"""
if __name__ == "__main__":#6
say_hello() #7,14
# 以上为解释器运行顺序
带参数的装饰器:
def debug(func):
def wrapper(*args, **kwargs):
print('[DEBUG]: enter {}()'.format(func.__name__))
return func(*args, **kwargs)
return wrapper
@debug
def say_hello(name, something):
print('hello!{}{}'.format(name, something))
say_hello('luozheng', '.')
"""
[DEBUG]: enter say_hello()
hello!luozheng.
"
高阶装饰器(附解释器解释顺序):
def logging(level): #2,11
def wrapper(func): #3,6,12,15
def inner_wrapper(*args, **kwargs): #7,16,21,31
print('[{level}]: enter function {func}()'.format( #22,32
level=level, #23,33
func=func.__name__)) #24,34
return func(*args, **kwargs) #25,28,35,38
return inner_wrapper #8,17
return wrapper #4,13
@logging(level='INFO') #1,5,9,26
def say(something):
print('say {}!'.format(something)) #27
# 此处使用的@语法,等同于
# say = logging(level='INFO')(say)
@logging(level='DEBUG') #10,14,18,36
def do(something):
print('do {}...'.format(something)) #37
if __name__ == '__main__': #19
say('hello') #20,29
do('my work') #30,39
"""
[INFO]: enter function say()
say hello!
[DEBUG]: enter function do()
do my work...
"""
类装饰器:
class logging(object): #1,4
def __init__(self, level='INFO'): #2,6
self.level = level #7
def __call__(self, func): # 接受函数,3,9
def wrapper(*args, **kwargs): #10,14
print('[{level}]: enter function {func}()'.format( #15
level=self.level, #16
func=func.__name__)) #17
func(*args, **kwargs) #18,21
return wrapper # 返回函数,11
@logging(level='INFO') #5,8,12,19
def say(something): #
print('say {}'.format(something)) #20
say('love you.') #13,22
print(say.__name__) # wrapper,23