This is mostly syntactic sugar but I'd like to access the items of a dictionary as object properties.
Example:
class CoolThing():
def __init__(self):
self.CoolDict = {'a': 1, 'b': 2}
and I'd like to have
my_cool_thing.a # => 1
my_cool_thing.b # => 2
Edit: some code of a potential solution with a nested structure with dot notation: 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__)
You want __getattr__
and __setattr__
, though you'll have to roll your own class (I'm not aware of any builtins, though namedtuple
might work if you don't need to change values much)
class AttrDict(dict):
def __getattr__(self, attr):
return self[attr]
def __setattr__(self, attr, value):
self[attr] = value
If you just want to access a sub-dictionary that way, you just change self
to 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
Note that __getattr__
is used after any other lookups fail, but if you want to ensure that your function is called first, you can use __getattribute__
Also note that self.cool_dict
does not exist on CoolThing
until after __init__
is called. My initial version of this would throw a maximum recursion depth exceeded, because as you created the class it would go to set self.cool_dict
in init, call __setattr__
, which would try to get self.cool_dict
so it could set [attr] = value
on it. Naturally it can't find cool_dict
yet, and so it will try to call __getattr__
again... which can't find cool_dict
and round and round it goes.
Another option would be to use a class-level variable instead, but that's probably not at all what you want :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With