最近我正在学习Python装饰器并使用functools.wraps
。
def a():
def b():
def c():
print('hello')
return c
return b
print a.__name__
#output:a
我理解为什么输出是a。但我不知道__name__
在以下代码中的变化。
def log(text):
def decorator(func):
def wrapper(*args, **kw):
print('%s %s():' % (text, func.__name__))
return func(*args, **kw)
return wrapper
return decorator
@log('...')
def simple():
print('*' * 20)
print simple.__name__
#output:wrapper
为什么输出是'wrapper'而不是'decorator'或'log'?
答案 0 :(得分:2)
一些基础知识:
@decorator
def f():
pass
相当于:
def f():
pass
f = decorator(f)
带args的装饰者:
@decorator(*args, **kwargs)
def f():
pass
相当于:
def f():
pass
decorator_instance = decorator(*args, **kwargs)
f = decorator_instance(f)
知道了,我们可能会将您的示例重写为:
def simple():
print('*' * 20)
log_instance = log('...')
simple = log_instance(simple)
让我们分析最后两行中发生的事情:
log_instance
是一个decorator
函数,其中的文本变量等于' ...' decorator
(无论text
值如何)返回名为wrapper的函数,simple
将替换为名为wrapper
的函数答案 1 :(得分:0)
当使用该函数/类作为参数调用时,装饰器的意思是用函数或类替换装饰器返回的内容。带参数的装饰器有点复杂,因为你首先调用外部方法(log
)来获得“参数化”装饰器(decorator
),然后你调用那个并获得最终函数({ {1}}),它将替换修饰函数(wrapper
)。
所以,给它一些结构,
simple
为参数调用log
并获取'...'
decorator
为参数调用decorator
并获取simple
wrapper
替换为simple
答案 2 :(得分:0)
@log('...')
def simple(...
相当于
def simple(...
simple = log('...')(simple)
所以实际调用log
,返回decorator
,用simple
作为参数调用,然后用decorator
的返回值替换,这是函数wrapper
,因此其__name__
为wrapper
。