解释Python装饰器的工作原理

时间:2014-02-18 06:03:20

标签: python decorator

这是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")

2 个答案:

答案 0 :(得分:3)

装饰器是在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

答案 1 :(得分:0)

这只是观察到在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(你好)

当你打电话

@helloGalaxy

hello()函数之前的@helloSolarSystem

hello将由helloGalaxy和helloSolarSystem

修饰

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

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