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?
An instance/object attribute is a variable that belongs to one (and only one) object. Every instance of a class points to its own attributes variables. These attributes are defined within the __init__ constructor.
A variable stored in an instance or class is called an attribute. A function stored in an instance or class is called a method.
To check if an object in python has a given attribute, we can use the hasattr() function. The function accepts the object's name as the first argument 'object' and the name of the attribute as the second argument 'name. ' It returns a boolean value as the function output.
A data attribute is exactly as it sounds; it's data, it is simply a property. A method is a procedure, an action, and this is exactly what a method attribute is.
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 the object
type as light as we could, and also supplying __slots__
to allow avoiding per-instance __dict__
in subtypes of object
, we supported small, specialized "value" types to the best of our ability.
Alex Martelli posted an awesome answer to your question. For anyone who is looking for a good way to accomplish arbitrary attributes on an empty object, do this:
class myobject(object):
pass
o = myobject()
o.anything = 123
Or more efficient (and better documented) if you know the attributes:
class myobject(object):
__slots__ = ('anything', 'anythingelse')
o = myobject()
o.anything = 123
o.anythingelse = 456
The rationale is that an instance of object()
is a degenerate special case. It "is" an object but it isn't designed to be useful by itself.
Think of object
as a temporary hack, bridging old-style types and classes. In Python 3.0 it will fade into obscurity because it will no longer be used as part of
class Foo( object ):
pass
f = Foo()
f.randomAttribute = 3.1415926
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With