2014-09-30 81 views
4

我正在使用前面討論的技術將字典轉換爲對象,以便我可以用點(。)概念作爲實例變量訪問字典的元素。將字典轉換爲對象時的問題

這是我在做什麼:

# Initial dictionary 
myData = {'apple':'1', 'banana':'2', 'house':'3', 'car':'4', 'hippopotamus':'5'} 

# Create the container class 
class Struct: 
    def __init__(self, **entries): 
     self.__dict__.update(entries) 

# Finally create the instance and bind the dictionary to it 
k = Struct(**myData) 

所以,現在,我可以這樣做:

print k.apple 

,其結果是:

1 

這工作,但是問題如果我嘗試將其他方法添加到「Struct」類,請開始。例如可以說,我補充說,僅僅是創建一個變量的簡單方法:

class Struct: 
    def __init__(self, **entries): 
     self.__dict__.update(entries) 

    def testMe(self): 
     self.myVariable = 67 

如果我做的:

k.testMe() 

我的字典對象被打破,「MYVARIABLE」插入與關鍵值「67」。所以,如果我做的:

print k.__dict__ 

我越來越:

{'apple': '1', 'house': '3', 'myVariable': 67, 'car': '4', 'banana': '2', 'hippopotamus': '5'} 

是有辦法解決這一問題?我有點理解發生了什麼,但不知道如果我需要完全改變我的方法,並用內部方法來構建一個類來處理字典對象,或者有更簡單的方法來解決這個問題嗎?

以下是原文鏈接: Convert Python dict to object?

感謝。

+0

屬性被存儲在可通過'OBJ .__ dict__'訪問所謂的*如字典* - 你有意選擇因爲你想讓它「看起來像一個真實的物體」,或者那是偶然的?因爲如果不是的話,你應該使用像'self._dict'這樣的東西(首先初始化),你會很好。 – 2014-09-30 17:47:46

+1

或者用不同的方式表達:是的,當然'myVariable'被插入到對象的'__dict__'中 - 這就是它應該如何工作的關鍵。這不是你想要的嗎?我不明白這是如何「打破」你的字典。 – 2014-09-30 17:51:03

+0

@LukasGraf嗨,感謝您的及時回覆。我剛剛按照該鏈接中的說明進行操作。讓我試試,但我懷疑,如果我不使用'__dict__',我不會獲得'.item'訪問權限。我現在會嘗試。 – symbolix 2014-09-30 17:51:04

回答

2

爲了您的需要,請勿將變量存儲在__dict__中。用你自己的字典,而是和覆蓋.__getattr__(用於print k.apple)和__setattr__(用於k.apple=2):

# Initial dictionary 
myData = {'apple':'1', 'banana':'2', 'house':'3', 'car':'4', 'hippopotamus':'5'} 

# Create the container class 
class Struct: 
    _dict = {} 
    def __init__(self, **entries): 
     self._dict = entries 

    def __getattr__(self, name): 
     try: 
      return self._dict[name] 
     except KeyError: 
      raise AttributeError(
       "'{}' object has no attribute or key '{}'".format(
        self.__class__.__name__, name)) 


    def __setattr__(self, name, value): 
     if name in self._dict: 
      self._dict[name] = value 
     else: 
      self.__dict__[name] = value 

    def testMe(self): 
     self.myVariable = 67 

    def FormattedDump(self): 
     return str(self._dict) 

# Finally create the instance and bind the dictionary to it 
k = Struct(**myData) 

print k.apple 
print k.FormattedDump() 
k.testMe() 
k.apple = '2' 
print k.FormattedDump() 

在備選方案中,如果你的FormattedDump()程序困擾着你,你可能只是修復:對象實例的

# Initial dictionary 
myData = {'apple':'1', 'banana':'2', 'house':'3', 'car':'4', 'hippopotamus':'5'} 

# Create the container class 
class Struct: 
    def __init__(self, **entries): 
     self.__dict__.update(entries) 
     self.public_names = entries.keys() 

    def testMe(self): 
     self.myVariable = 67 

    def GetPublicDict(self): 
     return {key:getattr(self, key) for key in self.public_names} 
    def FormattedDump(self): 
     return str(self.GetPublicDict()) 

# Finally create the instance and bind the dictionary to it 
k = Struct(**myData) 

print k.apple 
print k.FormattedDump() 
k.testMe() 
k.apple = '2' 
print k.FormattedDump() 
+0

因爲你將會擴展'__setattr__',所以刪除了我的回答。 – 2014-09-30 18:14:39

+0

然而,您應該在'__getattr__'中引發'AttributeError',否則'self._dict'中的缺失鍵會引發'KeyError',這對於虛線屬性訪問來說是相當意想不到的。 – 2014-09-30 18:16:20

+0

嗨!非常感謝你的幫助!我會立即嘗試。這已經很酷了,感謝所有的幫助和建議。 – symbolix 2014-09-30 18:26:50