【问题标题】:How decorator works? [duplicate]装饰器是如何工作的? [复制]
【发布时间】:2014-04-14 13:20:08
【问题描述】:

我试图弄清楚装饰器在 python 中是如何工作的。 但是,有两件事我无法说清楚,所以如果有人帮助我了解装饰器在 python 中的工作原理,我将不胜感激!

这是我刚刚编写的示例代码,以了解其工作原理。

In [22]: def deco(f):
   ....:     def wrapper():
   ....:         print("start")
   ....:         f()
   ....:         print("end")
   ....:     return wrapper

In [23]: @deco
   ....: def test():
   ....:     print("hello world")
   ....:     

输出 1

In [24]: test()
start
hello world
end

我不明白的第一件事是为什么当我调用 test() 时它会输出“start”、“hello world”、“end”。 我了解到,当我调用 test() 时,它会在内部调用“deco(test)”。 如果是这样,它应该返回一个“包装器”函数对象而不是输出字符串。 但是,它会输出字符串作为结果。我想知道它在内部是如何完成这项工作的。

输出 2

In [28]: i = deco(test)

In [29]: i
Out[29]: <function __main__.wrapper>

In [30]: i()
start
start
hello world
end
end

我调用“deco(test)”只是为了看看它输出的结果。 如上所示,它返回“wrapper”函数对象,在我将其分配给一个变量并调用“wrapper”函数后,它输出两个“start”、一个“hello world”和两个“end”。 内部发生了什么?为什么“start”和“end”分别输出两次?

谁能帮我理解这是如何工作的?

【问题讨论】:

  • 就像 Preet 说的,请查看链接线程以获取装饰器的解释。关于第二个输出, start 和 end 被打印两次,因为您再次将测试函数包装在装饰器中。它已经在第 23 行进行了装饰。

标签: python python-decorators


【解决方案1】:

我了解到,当我调用 test() 时,它会在内部调用“deco(test)”。如果是这样,它应该返回一个“包装器”函数对象而不是输出字符串。但是,它会输出字符串作为结果。我想知道它在内部是如何完成这项工作的。

不完全是,应用装饰器是语法糖(意味着做一些原本可能的事情的好方法)。等价的操作是

def test():
    print("Hello, world!")
test = deco(test) # note that test is overwritten by the wrapper that deco returns

为了说明这一点,请考虑以下示例

>>> def deco(f):
...     print 'applying deco' # this will print when deco is applied to test
...     def wrapper():
...             print("start")
...             f()
...             print("end")
...     return wrapper
...
>>> @deco
... def test():
...     print("Hello world!")
...
applying deco

请注意,只要定义了函数,就会应用装饰器。这与上面的“等效操作”相匹配。

在第二种情况下,当您手动将 deco 应用于已修饰的测试函数时,您会看到双重打印语句。

【讨论】:

  • 哦,,,所以,当装饰器应用于测试函数时,测试函数被包装函数覆盖。这就是为什么当调用 test() 时,它会输出字符串。我懂了!!!谢谢!
  • 应用装饰器是这个“test = deco(test)”的语法糖。好的!!我得到了它!现在对我来说完全有道理!!非常感谢!!
猜你喜欢
  • 2016-03-14
  • 2018-06-11
  • 2017-09-12
  • 2011-07-25
  • 2020-04-08
  • 2016-01-24
  • 2018-01-20
  • 1970-01-01
  • 2017-08-28
相关资源
最近更新 更多