在Python中装饰装饰器
问题描述:
我无法理解在Python(2.7.2)中如何装饰装饰器。我有以下一段代码:在Python中装饰装饰器
def verbose(function):
print 'i am verbose and func is ' + function.__name__
def wrapper2(func):
print 'func is ' + repr(func)
result = function(func)
return result
return wrapper2
@verbose
def more(function):
print 'i am more and func is ' + function.__name__
def wrapper1(*args, **kwargs):
print 'args' + repr(args)
result = function(*args)
return result
return wrapper1
@more
def hello(*args):
print(sum(args))
当我运行:
>>> hello(1,2,3)
这就是我得到:
i am verbose and func is more
func is <function hello at 0x1015338c0>
i am more and func is hello
args(1, 2, 3)
6
我无法想象调用序列生成此输出。我认为下面的调用仍然会生成相同的输出,我很想了解装饰器在这个特定示例中的工作方式。
>>> verbose(more)(hello)(1,2,3)
i am verbose and func is more
func is <function hello at 0x101533d70>
i am more and func is hello
args(1, 2, 3)
6
答
您还原为verbose(more)(hello)(1,2,3)
是正确的。但是,这些呼叫发生在不同的时间。记住这一点:
@deco
def func():
# whatever
是一样的:
def func():
# whatever
func = deco(func)
所以当你定义more
,verbose
被调用。当您定义hello
时,将调用more
(装饰版)。您的代码相当于:
def verbose(function):
print 'i am verbose and func is ' + function.__name__
def wrapper2(func):
print 'func is ' + repr(func)
result = function(func)
return result
return wrapper2
def more(function):
print 'i am more and func is ' + function.__name__
def wrapper1(*args, **kwargs):
print 'args' + repr(args)
result = function(*args)
return result
return wrapper1
more = verbose(more)
def hello(*args):
print(sum(args))
hello = more(hello)
这应该说明哪些函数调用正在发生时。请注意,当您调用hello(1, 2, 3)
时,more
和verbose
都不会被调用。当装饰函数是定义为时,调用装饰器时不会调用它。在通话时,所谓的装饰器的返回值(即在您的示例中的功能wrapper1
和wrapper2
)。
+0
谢谢@BrenBarn – Codenobar 2014-09-24 08:25:02
由于您在尝试在定义之前使用装饰器,因此您的代码会生成NameError。你真的在'more'上面定义了'verbose'吗?另外,即使你这样做了,你显示的一些输出将会在'hello'被定义时产生,有些时候'more'被定义,而不是当'hello'被调用时。在你的例子中,什么是'python >>'提示符? – BrenBarn 2014-09-24 06:57:00
修复名称错误。是的,当我定义'more'和一些定义'hello'方法时,会产生输出的一部分。我只是在这里粘贴,以确保两种调用方式生成相同的输出。 – Codenobar 2014-09-24 07:06:18