Underlying mechanism for Python class member lookup

By : user
Source: Stackoverflow.com
Question!

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!

By : user


Answers

In python, each class and each instance gets a dictionary. A uses the class dictionary. The examples for classes B and C are using the instance dictionaries. B will not be equivalent to A -- python is not intended to be fast, it would be very hard if not impossible to prove that no instances of B would get mutated.

Proof:



Under the hood, does member lookup function in the same way for each class?

Unless you override __getattribute__, the attribute lookup first checks object attributes, then type attributes. It doesn't care how the class came to be.

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.

In A, attributes are stored in A.__dict__, i.e. on the type. In B and C, attributes are stored in the self.__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 between B and C.



This video can help you solving your question :)
By: admin