Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't you add attributes to object in python? [duplicate]

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

like image 543
quano Avatar asked Aug 16 '09 20:08

quano


People also ask

Why attribute error occurs in Python?

Because the variable is an integer type it does not support the append method. So in this type of problem, we get an error called “AttributeError”. Suppose if the variable is list type then it supports the append method. Then there is no problem and not getting”Attribute error”.

Does Python object have attributes?

Since everything in Python is an object and objects have attributes (fields and methods), it's natural to write programs that can inspect what kind of attributes an object has. For example, a Python program could open a socket on the server and it accepts Python scripts sent over the network from a client machine.

Can I add an attribute to a class Python?

Adding attributes to a Python class is very straight forward, you just use the '. ' operator after an instance of the class with whatever arbitrary name you want the attribute to be called, followed by its value.


2 Answers

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

like image 61
ars Avatar answered Sep 17 '22 12:09

ars


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.

like image 39
D.Shawley Avatar answered Sep 19 '22 12:09

D.Shawley