71

(Written in Python shell)

>>> o = object() >>> o.test = 1 Traceback (most recent call last): File "<pyshell#45>", line 1, in <module> o.test = 1 AttributeError: 'object' object has no attribute 'test' >>> class test1: pass >>> t = test1() >>> t.test Traceback (most recent call last): File "<pyshell#50>", line 1, in <module> t.test AttributeError: test1 instance has no attribute 'test' >>> t.test = 1 >>> t.test 1 >>> class test2(object): pass >>> t = test2() >>> t.test = 1 >>> t.test 1 >>> 

Why doesn't object allow you to add attributes to it?

0

2 Answers 2

58

Notice that an object instance has no __dict__ attribute:

>>> dir(object()) ['__class__', '__delattr__', '__doc__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__'] 

An example to illustrate this behavior in a derived class:

>>> class Foo(object): ... __slots__ = {} ... >>> f = Foo() >>> f.bar = 42 Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'Foo' object has no attribute 'bar' 

Quoting from the docs on slots:

[...] The __slots__ declaration takes a sequence of instance variables and reserves just enough space in each instance to hold a value for each variable. Space is saved because __dict__ is not created for each instance.

EDIT: To answer ThomasH from the comments, OP's test class is an "old-style" class. Try:

>>> class test: pass ... >>> getattr(test(), '__dict__') {} >>> getattr(object(), '__dict__') Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'object' object has no attribute '__dict__' 

and you'll notice there is a __dict__ instance. The object class may not have a __slots__ defined, but the result is the same: lack of a __dict__, which is what prevents dynamic assignment of an attribute. I've reorganized my answer to make this clearer (move the second paragraph to the top).

Sign up to request clarification or add additional context in comments.

2 Comments

So, you are saying that the object class is using __slots__ in one way or another, to prevent assignment of instance members. Is this an assumption or a fact (i.e. is it in the implementation of object)? Because the mere absence of _\dict__ from an object instance is not indicative. Instances of the OP's test1 class show the same missing __dict__ when called with dir(), but allow nevertheless assignment of instance members.
@ThomasH, please see the note I added to the answer.
5

Good question, my guess is that it has to do with the fact that object is a built-in/extension type.

>>> class test(object): ... pass ... >>> test.test = 1 >>> object.test = 1 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: can't set attributes of built-in/extension type 'object' 

IIRC, this has to do with the presence of a __dict__ attribute or, more correctly, setattr() blowing up when the object doesn't have a __dict__ attribute.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.