这主要是语法糖,但我想将字典中的项目作为对象属性进行访问。
示例:
class CoolThing():
def __init__(self):
self.CoolDict = {'a': 1, 'b': 2}
我希望
my_cool_thing.a # => 1
my_cool_thing.b # => 2
编辑:带有点表示法的嵌套结构的潜在解决方案的一些代码:device.property.field
class Parameters():
def __init__(self, ids, devices):
self._ids = ids
self._devices = devices
for p in self._devices:
p = p[0]
if self.__dict__.get(p.device) is None:
self.__dict__[p.device] = SmartDict()
else:
if self.__dict__[p.device].get(p.property) is None:
self.__dict__[p.device][p.property] = SmartDict()
else:
if self.__dict__[p.device][p.property].get(p.field) is None:
self.__dict__[p.device][p.property][p.field] = ParameterData(p)
class SmartDict():
def __init__(self):
self.__dict__ = {}
def __getitem__(self, k):
return self.__dict__[k]
def __setitem__(self, k, v):
self.__dict__[k] = v
def get(self, k):
return self.__dict__.get(k)
def __len__(self):
return len(self.__dict__)
答案 0 :(得分:5)
你想要__getattr__
和__setattr__
,虽然你必须推出自己的课程(我不知道任何内置课程,但namedtuple
可能会有效你不需要多改变价值观
class AttrDict(dict):
def __getattr__(self, attr):
return self[attr]
def __setattr__(self, attr, value):
self[attr] = value
如果您只是想以这种方式访问子词典,只需将self
更改为self.cool_dict
class CoolThing:
def __init__(self):
self.cool_dict = {'a': 1, 'b': 2}
def __getattr__(self, attr):
return self.cool_dict[attr]
def __setattr__(self, attr, value):
# Note, you'll have to do this for anything that you want to set
# in __init__.
if attr == 'cool_dict':
super().__setattr__(attr, value)
else:
self.cool_dict[attr] = value
请注意,在任何其他查找失败后,使用了__getattr__
,但如果您想确保首先调用您的函数,则可以使用__getattribute__
另请注意,在self.cool_dict
调用CoolThing
之前,__init__
<{1}}我的初始版本会超出最大递归深度,因为在创建类时,它会在init中设置self.cool_dict
,调用__setattr__
,这会尝试获得self.cool_dict
它可以设置[attr] = value
。当然,它还无法找到cool_dict
,因此它会尝试再次调用__getattr__
...无法找到cool_dict
并绕过它。
另一种选择是使用类级变量,但这可能根本不是你想要的那样:)
答案 1 :(得分:5)
CoolDict
已经存在,它名为__dict__
:
>>> class CoolThing(object):
... def __init__(self):
... self.__dict__['a'] = 1
... self.__dict__['b'] = 2
...
>>> thing = CoolThing()
>>> thing.a
1
>>> thing.b
2
>>> thing.c = 3
>>> thing.__dict__
{'a': 1, 'b': 2, 'c': 3}