I'm really confused by the following code sample:
class Meta_1(type):
def __call__(cls, *a, **kw): # line 1
print("entering Meta_1.__call__()")
print(cls) # line 4
print(cls.mro()) # line 5
print(super(Meta_1, cls).__self__) # line 6
rv = super(Meta_1, cls).__call__(*a, **kw) # line 7
print("exiting Meta_1.__call__()")
return rv
class Car(object, metaclass=Meta_1):
def __new__(cls, *a, **kw):
print("Car.__new__()")
rv = super(Car, cls).__new__(cls, *a, **kw)
return rv
def __init__(self, *a, **kw):
print("Car.__init__()")
super(Car,self).__init__(*a, **kw)
if __name__ == '__main__':
c = Car()
The print message for this code is:
entering Meta_1.__call__()
<class '__main__.Car'> # line 4
[<class '__main__.Car'>, <class 'object'>] # line 5
<class '__main__.Car'> # line 6
Car.__new__()
Car.__init__()
exiting Meta_1.__call__()
The result shows that cls
of line 4 is the Car
class and its MRO list is:
[<class '__main__.Car'>, <class 'object'>]
However, line 6 shows that super(Meta_1, cls).__self__
is also the Car
class.
I am really confused that:
- In line 7, It seems that
super(Meta_1, cls).__call__(*a, **kw)
eventually lead totype.__call__
. But, to my knowledge,super(arg1, arg2)
will look into the MRO of the second input argument to find the first input argument, and return the next class to it. But in line 6 and 7 of my code, the MRO for 2nd argument(Car
), does not contain the 1st input argument(Meta_1
), you cannot findMeta_1
in the MRO forCar
. so why wouldsuper(Meta_1, cos)
take us to invoketype.__call__
??
2. if super(Meta_1, cls).__self__
is the Car
class, then line 7 means it's Car
's __call__
that's being called? But calling the Car
class took us to line 1 in the first place, right? wouldn't that be a loop?