2014-02-18 64 views
1

這是一個python裝飾器的例子。我無法理解它的工作方式。請解釋給出的例子的控制流程。我會非常感激。解釋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") 
+0

下面是一個可能有所幫助的小教程:https://www.codementor.io/python/tutorial/introduction-to-decorators – Sheena

回答

2

裝飾是用於在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)) 

通過代hellohelloSolarSystem,然後結果爲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 
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意味着你好= helloGalaxy(你好)

同樣,@helloSolarSystem意味着你好= helloSolarSystem(你好)

當你叫

@helloGalaxy

@helloSolarSystem之前你好()函數

你好將由helloGalaxy和helloSolarSystem

所以它new_function()將由helloSolarSystem()覆蓋。

在調用hello(「Earth」)之前,函數hello由helloSolarSystem()和helloGalaxy()裝飾器的newFunction()裝飾。