我有一个带有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)
答案 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所说,这通常不是一个好主意。)