Reputation: 720
I am using a bunch class to transform a dict to an object.
class Bunch(object):
""" Transform a dict to an object """
def __init__(self, kwargs):
self.__dict__.update(kwargs)
The problem is , i have a key with a dot in its name({'test.this':True}).
So when i call:
spam = Bunch({'test.this':True})
dir(spam)
I have the attibute:
['__class__',
'__delattr__',
...
'__weakref__',
'test.this']
But i can't access it:
print(spam.test.this)
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-7-ea63f60f74ca> in <module>()
----> 1 print(spam.test.this)
AttributeError: 'Bunch' object has no attribute 'test'
i got an AttributeError.
How can i access this attribute?
Upvotes: 5
Views: 4317
Reputation: 1436
A correct suggestion would be to avoid using dot in the variables. And even if we use somehow, its better to get it using getattr.
getattr(spam, 'test.this')
If we are being stubborn by avoid standards so this may help.
class Objectify(object):
def __init__(self, obj):
for key in obj:
if isinstance(obj[key], dict):
self.__dict__.update(key=Objectify(obj[key]))
else:
self.__dict__.update(key=obj[key])
class Bunch(object):
""" Transform a dict to an object """
def __init__(self, obj, loop=False):
for key in obj:
if isinstance(obj[key], dict):
self.__dict__.update(key=Objectify(obj[key]))
else:
self.__dict__.update(key=obj[key])
spam1 = Bunch({'test': {'this': True}})
print(spam1.test.this)
spam2 = Bunch({'test': {'this': {'nested_this': True}}})
print(spam2.test.this.nested_this)
Not provided test.this as the key. You may want to create a nested dict iterating through the keys having dots.
Upvotes: 0
Reputation:
Implement __getitem__(self, key)
:
class D():
def __init__(self, kwargs):
self.__dict__.update(kwargs)
def __getitem__(self, key):
return self.__dict__.get(key)
d = D({"foo": 1, "bar.baz": 2})
print(d["foo"])
print(d["bar.baz"])
Edit:
I don't recommend accessing d.__dict__
directly from a client of a D
instance. Client code like this
d = D({"foo": 1, "bar.baz": 2})
print(d.__dict__.get("bar.baz"))
is trying to reach into the underpants of d
and requires knowledge about implementation details of D
.
Upvotes: 2