matt.LLVW
matt.LLVW

Reputation: 720

How to access an object attribute with a dot in its name

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

Answers (4)

Reck
Reck

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

user9455968
user9455968

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

Aran-Fey
Aran-Fey

Reputation: 43246

You can use getattr:

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

Alternatively, you can get the value from the object's __dict__. Use vars to get spam's dict:

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

Upvotes: 4

Sagar Ruchandani
Sagar Ruchandani

Reputation: 95

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

Upvotes: -1

Related Questions