【问题标题】:Understanding decorator behaviour了解装饰器行为
【发布时间】:2018-01-17 13:49:42
【问题描述】:

我想了解这段代码中的装饰器行为

abc.py

def my_decorator_module(some_function):
    def wrapper():
        num = 10
        if num == 10:
            print('yess')
        else:
            print('no')

        some_function()

        print('print after some_function() called')

    return wrapper()

并将这个函数称为装饰器

x.py

from abc import my_decorator_module

@my_decorator_module
def just_some_function():
    print("Wheee!")

输出是

yess
Wheee!
print after some_function() called

执行x.py文件时我没有在x.py文件中调用just_some_function()的事件返回我的输出,为什么?

【问题讨论】:

    标签: python python-3.x decorator


    【解决方案1】:

    因为您在从外部装饰函数返回之前调用了wrapper。不要那样做。

    return wrapper   # not wrapper()
    

    tutorial you're following 早些时候引入了返回函数的概念,而不是调用它们并返回它们的结果;这就是你需要在这里做的事情。

    【讨论】:

      【解决方案2】:

      您没有明确调用just_some_function(),但您的“装饰者”确实如此,参见最后一行:

      def my_decorator_module(some_function):
          def wrapper():
              num = 10
              if num == 10:
                  print('yess')
              else:
                  print('no')
      
              some_function()
      
              print('print after some_function() called')
      
          # here !!!   
          return wrapper()
      

      这实际上是一个错误的实现——你的装饰器不应该返回调用wrapper的结果,而是返回wrapper函数本身:

          return wrapper
      

      如果你不明白为什么:@decorator 语法只是语法糖,所以这样:

      @decorator
      def somefunc():
          print("somefunc")
      

      实际上只是一个捷径:

      def somefunc():
          print("somefunc")
      
      somefunc = decorator(somefunc)
      

      所以你的装饰器必须返回一个函数对象(或任何可调用的 FWIW),通常 - 但不一定 - 一些负责调用装饰函数(并最好返回结果)的包装器。

      【讨论】:

        猜你喜欢
        • 2020-06-30
        • 1970-01-01
        • 2017-09-20
        • 2015-01-29
        • 2017-08-18
        • 2018-10-03
        • 2016-05-19
        • 2016-03-12
        • 2021-04-27
        相关资源
        最近更新 更多