2015-10-09 99 views
5

以下是Local類從werkzeug__init__方法:`object .__ setattr __(self,...,...)`而不是`setattr(self,...,...)`?

def __init__(self): 
    object.__setattr__(self, '__storage__', {}) 
    object.__setattr__(self, '__ident_func__', get_ident) 

我不明白這個代碼兩件事情:

  1. 他們爲什麼寫

    object.__setattr__(self, '__storage__', {}) 
    

    而不是簡單的

    `setattr(self, '__storage__', {})` 
    
  2. 爲什麼他們甚至用__setattr__如果可以簡單地寫

    self.__storage__ = {} 
    

回答

6

這確保使用默認的Python定義__setattr__。如果該類已重寫__setattr__以執行非標準行爲,則通常會使用此類行爲,但您仍希望訪問原始__setattr__行爲。

在WERKZEUG的情況下,如果你看一下Local類,你會看到__setattr__的定義是這樣的:

def __setattr__(self, name, value): 
    ident = self.__ident_func__() 
    storage = self.__storage__ 
    try: 
     storage[ident][name] = value 
    except KeyError: 
     storage[ident] = {name: value} 

相反在對象的字典設置的屬性,它設置他們在__storage__之前已初始化的字典。爲了完全設置__storage__屬性(以便稍後可以像self.__storage__那樣訪問它),必須使用來自對象的原始定義__setattr__,這就是在構造函數中使用尷尬表示法的原因。

+1

我只是補充一點,儘管在源代碼中看起來很尷尬,但它爲該類的用戶提供了一個很好的界面。 –

1

因爲同一類定義__setattr__這需要繞過,因爲第一行說self.__ident_func__()這將不工作尚未。

2

他們想明確地使用基地object.__setattr__實施,而不是繼承鏈中其他地方可能重寫的方法實例方法。 Local實現它自己的__setattr__,所以這避免了這一點。

相關問題