【问题标题】:Explain how Python decorator works [duplicate]解释 Python 装饰器的工作原理 [重复]
【发布时间】:2014-02-18 06:03:20
【问题描述】:

这是一个python装饰器的例子。我无法理解它的工作方式。请向我解释给定示例的控制流程。我将非常感激。

def helloSolarSystem(original_function):
   def new_function(*args, **kwargs):
        original_function(*args, **kwargs)  
        print("Hello, solar system!")
   return new_function

def helloGalaxy(original_function):
    def new_function(*args, **kwargs):
        original_function(*args, **kwargs)  
        print("Hello, galaxy!")
    return new_function

@helloGalaxy
@helloSolarSystem
def hello(targetName=None):
     if targetName:
        print("Hello, " +  targetName +"!")
     else:
        print("Hello, world!")
hello("Earth")

【问题讨论】:

标签: python decorator


【解决方案1】:

装饰器是在 Python 中应用 higher-order functions 的语法糖。高阶函数是将一个或多个函数作为输入并返回一个函数的函数。即

h(x) = f(g(x))

这里的f() 是一个高阶函数,它接受单个参数的函数g(x),并返回一个单个参数的函数h(x)。您可以将f() 视为修改g() 的行为。

高阶函数是composable(根据定义),所以在你的具体例子中,装饰器语法,

@helloGalaxy
@helloSolarSystem
def hello(targetName=None):
    ...

等价于,

hello = helloGalaxy(helloSolarSystem(hello))

通过将hello 代入helloSolarSystem,然后将其结果代入helloGalaxy,我们得到等效的函数调用,

def hello(targetName=None):
    if targetName:                            |        
        print("Hello, " + targetName + "!")   |  (1)  |
    else:                                     |       |  (2)   |
        print("Hello, world!")                |       |        |  (3)
    print("Hello, solar system!")                     |        |
    print("Hello, galaxy!")                                    |

其中(1)是原hello()的应用,(2)是应用,

def helloSolarSystem(original_function):
    def new_function(*args, **kwargs):
        original_function(*args, **kwargs)   <-- (1)
        print("Hello, solar system!")
    return new_function

和(3)是应用,

def helloGalaxy(original_function):
    def new_function(*args, **kwargs):
        original_function(*args, **kwargs)   <-- (2)
        print("Hello, galaxy!")
    return new_function

【讨论】:

    【解决方案2】:

    这只是观察到,在 Python 中,函数和其他所有东西一样都是对象。啊,包含变量的函数,你没那么特别!

    >>> issubclass(int, object) # all objects in Python inherit from a common baseclass
    True
    >>> def foo():
    ...     pass
    >>> foo.__class__ # 1
    <type 'function'>
    >>> issubclass(foo.__class__, object)
    True
    

    在你的例子中, @helloGalaxy 暗示 hello = helloGalaxy(hello)

    同样,@helloSolarSystem 暗示 hello = helloSolarSystem(hello)

    当你打电话时

    @helloGalaxy

    hello() 函数之前的@helloSolarSystem

    hello 将被 helloGalaxy 和 helloSolarSystem 装饰

    所以 new_function() 将被 helloSolarSystem() 覆盖。

    在调用 hello(“Earth”) 之前,函数 hello 被 helloSolarSystem() 和 helloGalaxy() 装饰器的 newFunction() 装饰。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-20
      • 1970-01-01
      • 2021-02-14
      • 2011-09-29
      • 2014-11-01
      • 2012-02-09
      • 1970-01-01
      相关资源
      最近更新 更多