Home > Blockchain >  Modifiying class attribute of parent
Modifiying class attribute of parent

Time:07-26

I recently encountered the following phenomenon and couldn't understand why it happens.

Consider the following:

class A:
     my_var = 0
     def __init__(self):
         type(self).my_var  = 1 
class B(A):
     pass

This results in:

In [3]: A.my_var is B.my_var
Out[3]: True

In [4]: A()
In [5]: A.my_var is B.my_var
Out[5]: True
In [6]: A.my_var
Out[6]: 1
In [7]: B.my_var
Out[7]: 1

But then:

In [8]: B()
In [9]: A.my_var is B.my_var
Out[9]: False
In [10]: A.my_var
Out[10]: 1
In [11]: B.my_var
Out[11]: 2

I do not understand why initiazling B(), casues my_var to "fork".

CodePudding user response:

When you call B(), B.__init__ resolves to A.__dict__['init'], since you did not override B.__init__. But type(self) still returns B, because it's an instance of B, not A, being initialized. As a result, you create B.my_var.

The assignment to an attribute is what makes this different from something like x = y, where x has to be defined in the current scope to avoid an UnboundLocalError exception. type(self).my_var = 1 "desugars" to B.my_var = B.my_var 1. (type(self) has to be evaluated first to identify on which type to find the __iadd__ attribute.) On the right-hand side, B.__dict__['my_var'] is not defined, so it evaluates to A.my_var. On the left, the attribute is created.

  • Related