The following code:
>>> class Foo: pass
>>> class Spam(Foo()): pass
will of course raise an error message:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Foo() takes no arguments
But the error info is a little bit odd. Seems that there are some processes when initializing class Spam
.
I wonder which step causes the error. In other words, why can't class inherit instance, the error message seems to indicate it indeed try something.
Note: I know there will be no error if write like this class Spam(Foo)
. But I do it on purpose. I just can't understand the error message, which indicates some procedures exist when class inheriting, I want to know which one procedure causes it.
Using a few dirty print statements we can get the sequence of events that is happening:
class Foo:
def __init__(self, *args, **kwargs):
print("__init__", self, args, kwargs)
def __new__(cls, *args, **kwargs):
print("__new__", cls, args, kwargs)
return super().__new__(cls)
inst = Foo()
class Spam(inst): pass
print(inst, Spam)
outputs
__new__ <class '__main__.Foo'> () {}
__init__ <__main__.Foo object at 0x0000019FFB399550> () {}
__new__ <class '__main__.Foo'> ('Spam', (<__main__.Foo object at 0x0000019FFB399550>,), {'__module__': '__main__', '__qualname__': 'Spam'}) {}
__init__ <__main__.Foo object at 0x0000019FFB399590> ('Spam', (<__main__.Foo object at 0x0000019FFB399550>,), {'__module__': '__main__', '__qualname__': 'Spam'}) {}
<__main__.Foo object at 0x0000019FFB399550> <__main__.Foo object at 0x0000019FFB399590>
So trying to inherit from an instance makes Python create a new instance of that class giving it parameters that would normally go to type.__new__
.
The reasons this happens is because types in python are objects: When deriving a class, python tries to get the correct meta class by calling type(base)
, which in this situation returns Foo
(the class), and then it tries to create an instance of that. ( I could have sworn python checks that type(base)
is a subclass of type
, but apparently that is wrong)