在python中装饰装饰器

时间:2014-09-24 06:55:13

标签: python python-decorators

我无法理解装饰装饰器如何在Python(2.7.2)中工作。我有以下代码:

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

1 个答案:

答案 0 :(得分:0)

您缩减为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)

这应该清楚说明哪些函数调用正在发生。请注意,当您调用 more时,verbosehello(1, 2, 3)都不会被调用。装饰函数定义时调用装饰器,而不是在调用它时调用。在调用时,所谓的装饰器的返回值(即示例中的函数wrapper1wrapper2)。