本文介绍了装饰器和关闭器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在经历
了解装饰器。

I am going through the How to make a chain of function decorators?to understand decorator.

在下面的示例中,由于封闭,包装函数可以访问 method_to_decorate。
但是,我不明白包装函数是否可以访问参数 self lie 。 / p>

In the following example, we see that "method_to_decorate" is accessible to wrapper function because of closures. But, I didn't understand how arguments self and lie are accessible to the wrapper function.

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?


推荐答案

返回的包装器替换装饰的函数,因此被视为方法。原始的 sayYourAge 接受了(自己,说谎),新的 wrapper

The returned wrapper replaces the decorated function, and is thus treated as a method. The original sayYourAge took (self, lie) and so does the new wrapper.

因此,当调用 l.sayYouAge(-3)时,您实际上是在调用嵌套的函数包装器,那时是绑定方法。绑定方法将传递 self ,并将 -3 分配给参数 lie 包装器调用 method_to_decorate(self,lie),将这些参数传递给原始的装饰函数。

So, when calling l.sayYouAge(-3) you are really calling the nested function wrapper, which is by that time a bound method. Bound methods get self passed in, and -3 is assigned to the argument lie. wrapper calls method_to_decorate(self, lie), passing these arguments on to the original decorated function.

请注意,自我谎言被硬编码为 wrapper()签名;它与装饰功能紧密绑定。这些不是从修饰后的函数中获取的,编写包装器的程序员事先知道包装后的版本需要哪些参数。请注意,包装程序根本没有必须将参数与带有修饰符的函数匹配。

Note that self and lie are hardcoded into the wrapper() signature; it is tightly bound to the decorated function. These were not taken from the decorated function, the programmer who wrote the wrapper knew beforehand what arguments would be expected of the wrapped version. Note that the wrapper doesn't have to match arguments with the decorated function at all.

您可以添加参数,例如:

You could add arguments, for example:

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

现在您可以制作了露西以不同的方式撒谎:

Now you can make Lucy lie about her age in different ways:

l.sayYourAge(-1, offset=1)  # will say "I am 32, what did you think?"

这篇关于装饰器和关闭器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-13 13:16