2016-02-10 37 views
7

我試圖理解某個類的某個單一裝飾器實現是如何工作的,但我只是感到困惑。裝飾器如何與Python中的類一起工作

下面的代碼:

def singleton(cls): 
    instance = None 

    @functools.wraps(cls) 
    def inner(*args, **kwargs): 
     nonlocal instance 
     if instance is None: 
      instance = cls(*args, **kwargs) 
     return instance 
    return inner 

@decocls = deco(cls)一個語法糖,所以在這段代碼,當我們定義cls類以及與此singleton裝飾包裹它,cls不會是一類了,而是一個功能。 Python會動態地搜索變量鏈接到的對象,所以後來我們嘗試創建我們的類的一個實例,並且這行代碼運行instance = cls(*args, **kwargs),我們不會進入無限遞歸嗎? cls此時不是類,它是一個函數,所以它應該調用自己,進入遞歸。

但它工作正常。創建一個singletone並且不會發生遞歸。它是如何工作的?

回答

4

功能inner通過局部變量cls關閉。

cls是對該類的引用。它從來沒有反彈到別的。

的裝飾機返回返回實例的功能,但是這並不影響內部cls變量是指

3

cls是對傳入裝飾器的原始類的引用。它保留了裝飾器被調用時的價值。它的值在裝飾器返回的函數中「陷入」;出於難以理解的原因,這被稱爲閉包。大多數功能是第一類對象的語言都具有此功能。

2
def singleton(cls): 
    instance = None 

    @functools.wraps(cls) 
    def inner(*args, **kwargs): 
     nonlocal instance 
     if instance is None: 
      instance = cls(*args, **kwargs) 
      print cls 
     return instance 
    return inner 

@singleton 
class TryMe(object): 
    pass 

m = TryMe() 
print m 

你將得到:

<class '__main__.TryMe'> 
<__main__.TryMe object at 0x10231c9d0>