Perhaps I woke up too early this morning, but this behaviour has me baffled:
Python 3.1.1 (r311:74483, Aug 17 2009, 17:02:12) [MSC v.1500 32 bit
(Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
--> test = object()
--> setattr(test, 'example', 123)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'object' object has no attribute 'example'
Shouldn't setattr() be creating the 'example' attribute? Any tips
greatly appreciated!
~Ethan~
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; I'm just
verifying that the behavior you see is not limited to 3.1.1.
Python 2.6.2 (release26-maint, Apr 19 2009, 01:56:41)
[GCC 4.3.3] on linux2
Type "help", "copyright", "credits" or "license" for more
information.
>>> class Foo(object): pass
...
>>> test = Foo()
>>> setattr(test, 'example', 123)
>>> test.example
123
>>> test = object()
>>> setattr(test, 'example', 123)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'object' object has no attribute 'example'
It's probably good to subclass object anyway, with something like:
class Record(object):
pass
But I do not know your use case.
>>> x = 1
>>> setattr(x, 'example', 123)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'int' object has no attribute 'example'
>>> x.example = 123
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'int' object has no attribute 'example'
>>>
There are limits to what you can do with the built-in types. No matter
how hard Python tries to make them look the same, ultimately the
built-in types are implemented differently from the types you create
yourself.
For efficiency reasons the attributes of the built-ins are stored in a
different way (that's more accessible to the C implementation) than
those of the declared types.
regards
Steve
--
Steve Holden +1 571 484 6266 +1 800 494 3119
See PyCon Talks from Atlanta 2010 http://pycon.blip.tv/
Holden Web LLC http://www.holdenweb.com/
UPCOMING EVENTS: http://holdenweb.eventbrite.com/
__metaclass__ = type
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
~Ethan~