In Python, if I define three classes:
class A:
name = 'oliver'
hailstone_ending = [4,2,1]
class B:
def __init__(self):
self.name = 'oliver'
self.hailstone_ending = [4,2,1]
class C:
pass
c = C()
c.name = 'oliver'
c.hailstone_ending = [4,2,1]
Under the hood, does member lookup function in the same way for each class? It seems that A would only need on dictionary to lookup members for all instances; C, on the other hand, would need to use a dictionary stored within each of these instances. If the interpreter were very intelligent, it could theoretically notice that all instances of B must include members name and hailstone_ending; therefore, it could be equivalent to A.
But on the other hand, if the del operation is permitted on the dictionary that looks up class members, the machinery for lookup in all of these classes may be equivalent, because the available members would be instance-dependent.
My interest is that I had some code that created several thousand classes of type C and I noticed it was very slow and memory hungry. I rewrote it recently a different way, and it feels more efficient (but I haven’t rigorously tested it, and so it may be the same).
Thanks a lot for your insight!
Unless you override
__getattribute__, the attribute lookup first checks object attributes, then type attributes. It doesn’t care how the class came to be.In
A, attributes are stored inA.__dict__, i.e. on the type. InBandC, attributes are stored in theself.__dict__, i.e. on the instance. Both dictionaries are present in all cases. There’s nothing more to it. And no, there is no difference betweenBandC.