I've got a toy python example where defining an inline metaclass as a function behaves differently than defining it as a class, and I'm trying to understand why:
>>> class Test(object):
... def __metaclass__(name, bases, nmspc):
... cls = type(name, bases, nmspc)
... def __init__(self, field, *args, **kwargs):
... print "making " + field
... super(cls, self).__init__()
... cls.__init__ = __init__
... return cls
...
>>> t = Test('lol')
making lol
>>> class Test2(Test): pass
...
>>> t = Test2('lol')
making lol
Versus:
>>> class Test(object):
... class __metaclass__(type):
... def __init__(cls, name, bases, nmspc):
... type.__init__(cls, name, bases, nmspc)
... def __init__(self, field, *args, **kwargs):
... print "making " + field
... super(cls, self).__init__()
... cls.__init__ = __init__
...
>>> t = Test('lol')
making lol
>>> class Test2(Test): pass
...
>>> t2 = Test2('lol')
making lol
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 7, in __init__
TypeError: __init__() takes at least 2 arguments (1 given)
So, what exactly is different between defining a class vs defining a function? They both end up returning a class through slightly different ways, since the modified cls.__init__ gets inherited one way but not the other.
I also checked similar construction by making a function and class declaration outside, and I get the same behavior.