2014-09-30 79 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