Can't set attributes on instance of "object" class
attributes, language-design, python
Solution
To support arbitrary attribute assignment, an object needs a `__dict__`: a dict associated with the object, where arbitrary attributes can be stored. Otherwise, there's nowhere to put new attributes.
An instance of `object` does not carry around a `__dict__` -- if it did, before the horrible circular dependence problem (since `dict`, like most everything else, inherits from `object`;-), this would saddle every object in Python with a dict, which would mean an overhead of many bytes per object that currently doesn't have or need a dict (essentially, all objects that don't have arbitrarily assignable attributes don't have or need a dict).
For example, using the excellent `pympler` project (you can get it via svn from here), we can do some measurements...:
>>> from pympler import asizeof
>>> asizeof.asizeof({})
144
>>> asizeof.asizeof(23)
16
You wouldn't want every `int` to take up 144 bytes instead of just 16, right?-)
Now, when you make a class (inheriting from whatever), things change...:
>>> class dint(int): pass
...
>>> asizeof.asizeof(dint(23))
184
...the `__dict__` is now added (plus, a little more overhead) -- so a `dint` instance can have arbitrary attributes, but you pay quite a space cost for that flexibility.
So what if you wanted `int`s with just one extra attribute `foobar`...? It's a rare need, but Python does offer a special mechanism for the purpose...
>>> class fint(int):
... __slots__ = 'foobar',
... def __init__(self, x): self.foobar=x+100
...
>>> asizeof.asizeof(fint(23))
80
...not quite as tiny as an `int`, mind you! (or even the two `int`s, one the `self` and one the `self.foobar` -- the second one can be reassigned), but surely much better than a `dint`.
When the class has the `__slots__` special attribute (a sequence of strings), then the `class` statement (more precisely, the default metaclass, `type`) does not equip every instance of that class with a `__dict__` (and therefore the ability to have arbitrary attributes), just a finite, rigid set of "slots" (basically places which can each hold one reference to some object) with the given names.
In exchange for the lost flexibility, you gain a lot of bytes per instance (probably meaningful only if you have zillions of instances gallivanting around, but, there are use cases for that).
Problem
So, I was playing around with Python while answering this question, and I discovered that this is not valid: ``` o = object() o.attr = 'hello' ``` due to an `AttributeError: 'object' object has no attribute 'attr'`. However, with any class inherited from object, it is valid: ``` class Sub(object): pass s = Sub() s.attr = 'hello' ``` Printing `s.attr` displays 'hello' as expected. Why is this the case? What in the Python language specification specifies that you can't assign attributes to vanilla objects? For other workarounds, see How can I create an object and add attributes to it?.