The Python Oracle

How can I create an object and add attributes to it?

Become part of the top 3% of the developers by applying to Toptal https://topt.al/25cXVn

--

Music by Eric Matyas
https://www.soundimage.org
Track title: Lost Jungle Looping

--

Chapters
00:00 Question
01:11 Accepted answer (Score 257)
01:44 Answer 2 (Score 438)
02:42 Answer 3 (Score 184)
03:17 Answer 4 (Score 54)
03:31 Thank you

--

Full question
https://stackoverflow.com/questions/2827...

Question links:
[Can't set attributes on instance of "object" class]: https://stackoverflow.com/questions/1529.../

Accepted answer links:
[Bunch]: http://code.activestate.com/recipes/5230...

Answer 3 links:
[types.SimpleNamespace]: https://docs.python.org/3/library/types....
[collections.namedtuple]: https://docs.python.org/3/library/collec...
[typing.NamedTuple]: https://docs.python.org/3/library/typing...
[PEP 557 -- Data Classes]: https://docs.python.org/3/library/datacl...
[try ]: https://pypi.python.org/pypi/attrs
[an example usage]: https://stackoverflow.com/a/42659500/427...
[pydantic]: https://pydantic-docs.helpmanual.io/

--

Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...

--

Tags
#python #class #object #attributes

#avk47



ANSWER 1

Score 477


The built-in object can be instantiated but can't have any attributes set on it. (I wish it could, for this exact purpose.) This is because it doesn't have a __dict__ to hold the attributes.


I generally just do this:

class Object(object):
    pass

obj = Object()
obj.somefield = "somevalue"

But consider giving the Object class a more meaningful name, depending on what data it holds.


Another possibility is to use a sub-class of dict that allows attribute access to get at the keys:

class AttrDict(dict):
    def __getattr__(self, key):
        return self[key]

    def __setattr__(self, key, value):
        self[key] = value

obj = AttrDict()
obj.somefield = "somevalue"

To instantiate the object attributes using a dictionary:

d = {"a": 1, "b": 2, "c": 3}

for k, v in d.items():
    setattr(obj, k, v)



ACCEPTED ANSWER

Score 283


You could use my ancient Bunch recipe, but if you don't want to make a "bunch class", a very simple one already exists in Python -- all functions can have arbitrary attributes (including lambda functions). So, the following works:

obj = lambda: None
obj.somefield = 'somevalue'

Whether the loss of clarity compared to the venerable Bunch recipe is OK, is a style decision I will of course leave up to you.




ANSWER 3

Score 191


There is types.SimpleNamespace class in Python 3.3+:

obj = someobject
obj.a = SimpleNamespace()
for p in params:
    setattr(obj.a, p, value)
# obj.a.attr1

collections.namedtuple, typing.NamedTuple could be used for immutable objects. PEP 557 -- Data Classes suggests a mutable alternative.

For a richer functionality, you could try attrs package. See an example usage. pydantic may be worth a look too.




ANSWER 4

Score 58


The mock module is basically made for that.

import mock
obj = mock.Mock()
obj.a = 5