I came across the following code while reading about metaclasses here, although I don't know if this distinction is specific to metaclasses and I suspect that it is not:
class MetaBase(type):
def __new__(mcl, name, bases, nmspc):
print('MetaBase.__new__\n')
return super(MetaBase, mcl).__new__(mcl, name, bases, nmspc)
def __init__(cls, name, bases, nmspc):
print('MetaBase.__init__\n')
super(MetaBase, cls).__init__(name, bases, nmspc)
Note that the super().__init__()
call omits the first argument. I'm guessing it's passed implicitly, as it's calling a method on whatever class is returned by super()
. That's the way I've usually seen such calls constructed, although they typically involve self
on a normal class rather than cls/mcl on a metaclass.
The super().__new__()
call passes mcl
explicitly, though. I don't understand why. The signatures look the same to me.
I am confused. Is super()
returning something different in each case, perhaps? What's happening here, and should I expect to be bitten by this when overriding other magic methods?
[edit: Someone suggested that this is a duplicate of this question, which describes their different functionality. While the same difference is exhibited in some of the examples there, I see nothing stating why it exists or whether it's unique to __new__
.]