这主要是语法糖,但我想访问字典的项目作为对象属性。
例子:
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__)
最佳答案
您需要 __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__
。我的初始版本会超出最大递归深度,因为当您创建类时,它会在 init 中设置 self.cool_dict
,调用 __setattr__
,它会尝试获取 self.cool_dict
以便它可以在其上设置 [attr] = value
。自然它还找不到 cool_dict
,所以它会再次尝试调用 __getattr__
......它找不到 cool_dict
并且一圈又一圈地进行。另一种选择是改用类级变量,但这可能根本不是您想要的:)