首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >自动调用装饰器

自动调用装饰器
EN

Stack Overflow用户
提问于 2019-11-14 09:24:50
回答 2查看 132关注 0票数 0

我正试图理解我的脚本的两个版本背后的逻辑,其中包含了在脚本中使用的装饰器。在其中一个脚本中,装饰器会被自动调用,甚至不会被调用。

脚本1:

代码语言:javascript
复制
def outer_decorator(input_function):
    def decorator(*args, **kwargs):
        print "Outer Decorator Called"
        output = input_function(*args, **kwargs)
        return output

    return decorator


class X:

    @outer_decorator
    def inner_decorator(input_function):
        def decorator(*args, **kwargs):
            output = input_function(*args, **kwargs)
            print "Inner Decorator Called"
            return output

        return decorator


    def z(self, a, b):
        """
        Function returns a - b
        """
        return a - b


x = X()
print(x.z(1, 2))

输出

-1

因此,每当我运行脚本1时,我都要创建一个class X对象,然后调用函数z。因此,在这种情况下,内部装饰函数不会在任何地方使用,因此不会被调用。

脚本2:

代码语言:javascript
复制
def outer_decorator(input_function):
    def decorator(*args, **kwargs):
        print "Outer Decorator Called"
        output = input_function(*args, **kwargs)
        return output

    return decorator


class X:

    @outer_decorator
    def inner_decorator(input_function):
        def decorator(*args, **kwargs):
            output = input_function(*args, **kwargs)
            print "Inner Decorator Called"
            return output

        return decorator

    @inner_decorator
    def s(self, a, b):
        """
        Function return a + b
        """
        return a + b

    def z(self, a, b):
        """
        Function returns a - b
        """
        return a - b


x = X()
print(x.z(1, 2))

因此,在上面的脚本中,我介绍了另一个使用function s@inner_decorator。但我仍然只调用function z of class x。但是,当我运行这个脚本时,我会得到以下输出。

外部装饰器称为

-1

那么,为什么@outer_decorator被调用并且正在打印呢?

是因为某个地方使用的装饰器是由解释器处理的吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-11-14 09:36:59

之所以调用outer_decorator,是因为您正在装饰装饰器本身。

代码语言:javascript
复制
def outer_decorator(input_function):
    def decorator(*args, **kwargs):
        print "Outer Decorator Called"
        output = input_function(*args, **kwargs)
        return output

    return decorator


class X:

    @outer_decorator
    def inner_decorator(input_function):
        def decorator(*args, **kwargs):
            output = input_function(*args, **kwargs)
            print "Inner Decorator Called"
            return output

        return decorator

这个表达式@outer_decorator实际上转换为inner_decorator = outer_decorator(inner_decorator),所以在您的代码中,虽然您没有显式地调用使用inner_decorator修饰的函数,但是当您用inner_decorator修饰function s时,它实际上调用了inner_decorated的修饰版本,这反过来又被称为outer_decorator中定义的decorator函数。

我希望这能把事情弄清楚。

票数 2
EN

Stack Overflow用户

发布于 2019-11-14 09:43:25

脚本1:

代码语言:javascript
复制
inner_decorator = outer_decorator(inner_decorator) # i.e. a function 
# object, no invocation

脚本2:这里:

代码语言:javascript
复制
@outer_decorator
    def inner_decorator(input_function):

这将被调用:

代码语言:javascript
复制
inner_decorator = outer_decorator(inner_decorator) # i.e. a function 
# object, no invocation

但是,在这里:

代码语言:javascript
复制
@inner_decorator
    def s(self, a, b):

这导致:

代码语言:javascript
复制
s = inner_decorator(s) = outer_decorator(inner_decorator)(s) # causes 
# invocation of outer_decorator
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58853322

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档