6

In python 3, you can add member variables to a custom object after the class declaration:

class a():
    pass

b = a()
b.c = 1 #okay
print(b.c) #outputs 1

However, doing the same for a list object throws an exception:

d = []
d.e = 1 #throws AttributeError: 'list' object has no attribute 'e'

Can someone explain why this is happening?

2 Answers 2

7

Not all objects support arbitrary attribute assignment.

Most built-in types don't, including lists, tuples, strings, bytes, dictionaries, sets, booleans, numeric types, etc. On the other hand, function objects do, as do module objects (you are adding new globals to that module when you do).

In other words, just because custom classes and instances support assignment, doesn't mean other types do too. To support arbitrary attributes these types would need to have a __dict__ dictionary per instance, a non-trivial memory cost for very little advantage, especially when a typical Python program creates a lot of instances of these types.

Note that when you use the __slots__ feature to save per-instance memory for custom classes, you cannot assign attributes to those instances either:

>>> class Foo:
...     __slots__ = ('spam', 'eggs')
...
>>> foo = Foo()
>>> foo.ham = "won't work"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Foo' object has no attribute 'ham'

Vice versa, you can subclass the built-in types, at which point the subclass does support arbitrary attribute assignment (as the subclass instances will have a __dict__ attribute):

>>> class FooList(list):
...     pass
...
>>> foo_list = FooList()
>>> foo_list.ham = 'This does work'

That is, unless you use __slots__ of course.

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

1 Comment

Oh that makes sense! Thank you. I'll mark this as the answer.
0

As Martijn Pieters have said, We can't add attribute to them. But you may inherit them and override setattribute() method to accomplish this.

1 Comment

There is no __setattribute__ method in Python. Maybe you meant object.__setattr__()? You don't need to use that method, subclasses can have arbitrary attributes assigned to them.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.