In python, it is illegal to create new attribute for an object instance like this
>>> a = object()
>>> a.hhh = 1
throws
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'object' object has no attribute 'hhh'
However, for a function object, it is OK.
>>> def f():
... return 1
...
>>> f.hhh = 1
What is the rationale behind this difference?
The reason function objects support arbitrary attributes is that, before we added that feature, several frameworks (e.g. parser generator ones) were abusing function docstrings (and other attribute of function objects) to stash away per-function information that was crucial to them — the need for such association of arbitrary named attributes to function objects being proven by example, supporting them directly in the language rather than punting and letting (e.g.) docstrings be abused, was pretty obvious.
To support arbitrary instance attributes a type must supply every one of its instances with a
__dict__— that’s no big deal for functions (which are never tiny objects anyway), but it might well be for other objects intended to be tiny. By making theobjecttype as light as we could, and also supplying__slots__to allow avoiding per-instance__dict__in subtypes ofobject, we supported small, specialized “value” types to the best of our ability.