2012-06-06 73 views
4

我有一個Python類存儲某些領域並具有一定的屬性,如如何從對象到字典進行自定義轉換?

class A(object): 
    def __init__(self, x, y): 
    self.x = x 
    self.y = y 

    @property 
    def z(self): 
    return self.x+1 

做什麼樣的變化,我需要做的類,這樣我可以做

>>> a = A(1,5) 
>>> dict(a) 
{'y':5, 'z':2} 

,我指定我想返回yz?我不能僅僅使用a.__dict__,因爲它將包含x而不是z。我希望能夠指定任何可以通過__getattribute__訪問的內容。

+0

難道你不能改寫是.__ dict__嗎? – tlunter

+0

'a .__ dict__'是Python類如何存儲字段的一個非常重要的部分,我很不情願搞亂它。 – murgatroid99

回答

11

添加__iter__()方法類返回對象的項目,如鍵值對的迭代器。然後,您可以將對象實例直接傳遞給構造函數dict(),因爲它接受一系列鍵 - 值對。

def __iter__(self): 
    for key in "y", "z": 
     yield key, getattr(self, key) 

如果你想這是一個更靈活一點,並允許在子類中很容易覆蓋的屬性列表(或程序),你可以在關鍵字列表存儲爲您的類的屬性:

_dictkeys = "y", "z" 

def __iter__(self): 
    for key in self._dictkeys: 
     yield key, getattr(self, key) 

如果你想在字典中包含的所有屬性(包括那些從父類繼承)嘗試:

def __iter__(self): 
    for key in dir(self): 
     if not key.startswith("_"): 
      value = getattr(self, key) 
      if not callable(value): 
       yield key, value 

這不包括與啓動成員「_」的d也可調用對象(例如,類和函數)。

+0

好的,第二個代碼塊正是我所需要的。 – murgatroid99

4

我認爲這個問題的一個合理的方法是創建一個asdict方法。當你說你想指定你想要dict包含哪些鍵時,我認爲你對在調用方法時傳遞的信息感到滿意。如果那不是你的意思,讓我知道。 (這併入kindall的指教。)

class A(object): 
    def __init__(self, x, y): 
     self.x = x 
     self.y = y 

    @property 
    def z(self): 
     return self.x+1 

    def asdict(self, *keys): 
     if not keys: 
      keys = ['y', 'z'] 
     return dict((key, getattr(self, key)) for key in keys) 

測試:

>>> A(1, 2).asdict('x', 'y') 
{'y': 2, 'x': 1} 
>>> A(1, 2).asdict() 
{'y': 2, 'z': 2} 
+0

我喜歡這個,因爲它可以讓你快速指定按鍵。不過,你可能想要一個默認列表。 – kindall

+0

@ kindall,好點,我喜歡這個想法。 – senderle

+0

這與我已有的非常相似,但我特別感興趣的是使用'dict'內建。 – murgatroid99

0

甲幼稚的方法來解決,這將是如下。它可能不足以滿足您的需求,但我只是指出它以防萬一您錯過了它。

>>> dict(y=a.y, z=a.z) 
>>> {'y': 5, 'z': 2} 
相關問題