How to access the attribute of an object with a dot in the name

I use the bundle class to convert 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 that 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 an 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 have an AttributeError.

How can I access this attribute?

+4
source share
4 answers

You can use getattr:

>>> getattr(spam, 'test.this')
True

Alternatively, you can get the value from the object __dict__. Use varsto get a spamdict:

>>> vars(spam)['test.this']
True
+4
source

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:

d.__dict__ D. ,

d = D({"foo": 1, "bar.baz": 2})
print(d.__dict__.get("bar.baz"))

D D.

+2

The correct suggestion would be to avoid using dots in variables. And even if we use it somehow, it's better to use it with getattr .

getattr(spam, 'test.this')

If we persist, avoid standards, so this can 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)

Test.this is not specified as a key. You might want to create a nested dict, iterating through the keys with dots.

0
source

Try spam ["test.this"] or spam.get ("test.this")

-1
source

Source: https://habr.com/ru/post/1695197/


All Articles