Answer: My explanation based on the link in above comment
Normal objects in python have internal dictionaries to store instances' attributes, since python allows to add custom attributes to class's instances. Due to its internal dictionary, the overhead is bigger. Namedtuple object doesn't allow to add attributes to furher instances, but only to its initial class what is a fair cost saving.
In below code you can see that instance of Foo namedtuple cannot add a new attribute and doesn't have an internal dictionary.
from collections import namedtuple
class Foo:
pass
f = Foo()
f.a = 1
print(f'f.__dict__: {f.__dict__}')
print(f'Attribute a: {f.a}')
Output
f.dict: {'a': 1}
Attribute a: 1
Foo = namedtuple("Foo", 'a,b')
f = Foo(1,2)
try:
print(f'f.__dict__: {f.__dict__}')
except Exception as e:
print(e)
Foo = namedtuple("Foo", 'a,b')
f = Foo(1,2)
try:
f.c = 3
except Exception as e:
print(e)
Output
Foo object has no attribute dict
'Foo' object has no attribute 'c'