0

我正在阅读如何制作功能装饰器链? 了解装饰器。

在下面的示例中,我们看到由于闭包,包装函数可以访问“method_to_decorate”。但是,我不明白包装函数如何访问参数selflie可访问性。

def method_friendly_decorator(method_to_decorate):
     def wrapper(self, lie):
         lie = lie - 3 # very friendly, decrease age even more :-)
         return method_to_decorate(self, lie)
     return wrapper

class Lucy(object):

    def __init__(self):
        self.age = 32

    @method_friendly_decorator
    def sayYourAge(self, lie):
        print "I am %s, what did you think?" % (self.age + lie)

l = Lucy()
l.sayYourAge(-3)
#outputs: I am 26, what did you think?
4

1 回答 1

6

返回wrapper的替换修饰函数,因此被视为方法。原来用的,新的也sayYourAge用。(self, lie)wrapper

因此,调用时l.sayYouAge(-3)您实际上是在调用嵌套函数wrapper,那时它是一个绑定方法。绑定方法被self传入,并-3分配给参数liewrapper调用method_to_decorate(self, lie),将这些参数传递给原始修饰函数。

注意selflie被硬编码到wrapper()签名中;它与装饰函数紧密绑定。这些不是从装饰函数中获取的,编写包装器的程序员事先知道包装后的版本需要什么参数。请注意,包装器根本不必参数与装饰函数匹配。

您可以添加参数,例如:

def method_friendly_decorator(method_to_decorate):
     def wrapper(self, lie, offset=-3):
         lie += offset # very friendly, adjust age even more!
         return method_to_decorate(self, lie)
     return wrapper

现在你可以用不同的方式让露西谎报她的年龄:

l.sayYourAge(-1, offset=1)  # will say "I am 32, what did you think?"
于 2013-01-11T11:08:21.243 回答