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_1in 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?