在Python中转换多个属性中的dict属性

时间:2014-12-08 13:27:33

标签: python oop dictionary

我有一个带有dict属性的类,如下所示:

class MyClass:

    def __init__(self):
        self.mydict = {'var1': 'value1', 'var2': 'value2', ...}

当我想获得价值时,我必须这样做:

cls = MyClass()
print(cls.mydict['var1'])
print(cls.mydict['var2'])

请直接在属性中获取值的解决方案是什么:

cls = MyClass()
print(cls.var1)
print(cls.var2)

5 个答案:

答案 0 :(得分:4)

使用setattr,您可以动态设置属性:

>>> class MyClass:
...     def __init__(self):
...         mydict = {'var1': 'value1', 'var2': 'value2'}
...         for key, value in mydict.items():
...             setattr(self, key, value)
...
>>> instance = MyClass()
>>> instance.var1
'value1'
>>> instance.var2
'value2'

答案 1 :(得分:3)

您可以在类中添加一个能够解析dict并插入相关属性的函数:

def assign_variables( self ):
  for key, val in self.mydict.items():
    setattr( self, key, val )

我在这里使用内置的setattr() function来设置动态名称/值的属性:

  

这是getattr()的对应物。参数是一个对象,一个字符串和一个任意值。该字符串可以命名现有属性或新属性。如果对象允许,该函数会将值赋给属性   例如,setattr(x, 'foobar', 123)相当于x.foobar = 123

在定义mydict变量之后,您可以在构造函数中调用此函数,甚至只需将循环放在构造函数中。

答案 2 :(得分:2)

另一种解决方案是实施__getattr__

class MyClass(object):
    def __init__(self):
        self.mydict = {'var1': 'value1', 'var2': 'value2', ...}

    def __getattr__(self, name):
        try:
            return self.mydict[name]
        except KeyError:
            raise AttributeError("object %s has no attribute '%s'" % (self, name))

答案 3 :(得分:-1)

您可以直接更新我认为对象的__dict__属性:

class MyClass:

    def __init__(self):
        self.mydict = {'var1': 'value1', 'var2': 'value2', ...}
        self.__dict__.update(self.mydict)

答案 4 :(得分:-1)

另一种方法是一起覆盖__getattr____setattr__,这避免了对类实例对象中的同一属性的两个对象引用({{1}中的一个OR value1 } {}和myobj.mydict['var1']value1的另一个OR:

myobj.__dict__['var1']

请注意,这样做意味着您无法向class MyClass(): def __init__(self): self.__dict__['_mydict'] = {'var1': 'value1', 'var2': 'value2'} #Note: using the @property (descriptor) is optional. I think it makes #things more convenient. @property def mydict(self): return self._mydict #NOTE: __getattr__ won't get called if att is found in self.__dict__ first! def __getattr__(self,att): if att in self.mydict: # or without using @property: if att in self._mydict: return self.mydict[att] # return self._mydict[att] else: raise AttributeError("'{n}' object has no attribute '{a}'".format(n = type(self).__name__, a = att)) def __setattr__(self,att,val): super().__setattr__(att, val) if att in self.mydict: self.mydict[att] = val # or without using @property: self._mydict[att] = val self.__delattr__(att) # remove duplicate copy of object reference to att 添加更多键值对,除非您直接调用该属性,例如:

mydict

另请注意,获取删除 myobj = MyClass() myobj.x = 1 myobj.mydict #note that result does not contain an entry for 'x' myobj.mydict['x'] = 2 myobj.mydict #now it does 成员将被任何现有的同名属性覆盖(不仅如此,但您可以&# 39;除非覆盖mydict以启用此行为,否则请删除mydict成员

__delattr__

如果你想改变这种行为,你必须覆盖#continuing the above code session assert myobj.x == 1 #myobj.x is coming from self.x, not from self._mydict['x'] myobj.var1 = 'a new value' myobj.var1 #results in 'a new value' as expected, but where is it coming from? assert myobj.mydict['var1'] == 'a new value' #Ah: it's coming from self._mydict as expected assert myobj.__dict__['var1'] #ERROR, as expected del myobj.x assert myobj.x == 2 #now myobj.x is coming from self._mydict['x'], self.x having been deleted del myobj.var1 #raises AttributeError; attributes in mydict can't be deleted (unless you also override __delattr__ (编辑:正如下面的bruno desthuilliers所说,这通常不是一个好主意。)