Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add member variables to a python list object

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?

like image 789
Hyder S M Avatar asked Nov 09 '15 06:11

Hyder S M


1 Answers

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.

like image 90
Martijn Pieters Avatar answered Oct 22 '22 15:10

Martijn Pieters