Python 3.1, object, and setattr()
Terry Reedy
tjreedy at udel.edu
Thu Apr 1 13:44:02 EDT 2010
On 4/1/2010 10:16 AM, Steve Howell wrote:
> On Apr 1, 6:46 am, Ethan Furman<et... at stoneleaf.us> wrote:
>
> On 2.6.2 the error seems to be limited to instances of object. If you
> subclass object, you are fine. I do not know why that is so;
As the other Steve said, object is a built-in class; user-defined
subclasses of object are user-defined classes. (And all other built-in
classes are built-in subclasses of object, at least in 3.x.)
Python objects can have either a fixed or variable set of attributes. By
default, instances of user classes have an attribute dictionary
(__dict__) for a variable set of attributes.
>>> a = A()
>>> a.a = 3
>>> a.a
3
>>> a.__dict__
{'a': 3}
The exception is when '__slots__ = xxx' is part of the class definition.
It instances then have a fixed set of attributes.
>>> class C(): __slots__ = ()
>>> c = C()
>>> c.a = 1
Traceback (most recent call last):
File "<pyshell#8>", line 1, in <module>
c.a = 1
AttributeError: 'C' object has no attribute 'a'
The error message means that 'a' is not in the fixed set of instance
attributes (as defined by __slots__) for class C.
In general, instances of built-in classes do not have such attribute
dictionaries and one their attribute set is fixed (and often empty). It
is as if built-in classes have '__slots__ = xxx' as part of their
definition. In particular, object and others act like they have
'__slots__ = ()', which means they have no instance attributes.
There are two exceptions among built-in classes that I know of: type and
'function', (whose instances are user-defined functions).
>>> def f(): pass
>>> f.__dict__
{} # standard dict just as with user class instances
Instances of type are more complicated:
>>> C.__dict__
<dict_proxy object at 0x00F682F0>
>>> C.z = 3
>>> C.z
3
so the dict_proxy for user classes is writable
but
>>> int.__dict__
<dict_proxy object at 0x00F5CDD0>
>>> int.z = 3
Traceback (most recent call last):
File "<pyshell#18>", line 1, in <module>
int.z = 3
TypeError: can't set attributes of built-in/extension type 'int'
wheres for builtins, it is not.
Terry Jan Reedy
More information about the Python-list
mailing list