Python 3.1, object, and setattr()

Terry Reedy tjreedy at
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>  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
 >>> 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

so the dict_proxy for user classes is writable

 >>> 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