2012-05-21 53 views
0

我正在使用一個Javascript風格的字典,如討論here。執行:Python點符號字典斷字連字符?

class DotDict(dict): 
    def __getattr__(self, attr): 
     return self.get(attr, None) 
    __setattr__= dict.__setitem__ 
    __delattr__= dict.__delitem__ 

我用這個結構有一段時間沒有問題,但最近需要一個字典,一個連字符鍵,這樣的:

foo = DotDict() 
    foo.a = 'a'  #Business as usual 
    foo.a-b = 'ab'  #Broken 

分配到foo.ab的結果:

SyntaxError: can't assign to operator 

由於' - '被看作是減號操作而不是鍵名稱的一部分,因此中斷。是否有另一種方式來創建一個點式成員訪問字典?

+1

有可能與SETATTR/GETATTR黑客做到這一點,但你不想這樣做,人們將讀取你的代碼不要你也這樣做。 (當然,你也不會得到點式會員訪問權) – zmo

+0

-1,因爲這不是有效的注意事項。 – jsbueno

回答

5

a-b在Python中不是一個有效的標識符。有效的標識符可以由字母,數字和下劃線組成(_)。任何其他字符在變量名中都不合法。

Is there another way to create a dictionary with dot-style member access?

不具有無效的標識符鍵點式接入方式

+0

它會被視爲python的解釋器爲'((foo.a) - (b))=('ab')'這是非法的,因爲表達式不能是左值。 – zmo

1

好吧,這是可能的,但你真的不想這樣做。

>>> class foo(): 
... pass 
... 
>>> f = foo() 
>>> setattr(f, 'foo-bar', 1) 
>>> getattr(f, 'foo-bar') 
1 
1

這是不可能的直接方式。最好的辦法是允許混合訪問 - 就像你已經做的那樣 - 並使用它。或者,也可以使用setattr()/getattr(),作爲Not_a_Golfer suggests

1

a-b不是一個有效的標識符,但被解釋爲使用運算符-的表達式。你可以設置這樣的字段:setattr(foo, 'a-b', 'ab')

3

我不確定你爲什麼感到驚訝。在JavaScript中,同樣也表達拋出一個錯誤:

>>> foo.a-b = 'ab' 
ReferenceError: invalid assignment left-hand side 

因此,正如在JavaScript中,回落到:

>>> foo['a-b'] = 'ab' 
0

它可能不適合你想實現的成語,但如果你要替換一個下劃線連字符,代碼將工作:

foo.a_b = 'ab'