Wrong class inheritance with self.__class__? [duplicate]
Question
I was working with inheritance in WTForms
.
I had next class:
class MyForm(WTForms):
...
def process(self, formdata=formdata, obj=None):
super(self.__class__, self).process(formdata=formdata, obj=obj)
And I had error (not always, but in some cases with similar forms - it is even more strange):
Maximum recursion depth have been exceeded
But when I've changed self.__class__
→ MyForm
everything was OK!
I don't get it... As I know they must be synonyms. What's wrong?
Solution
They are not synonyms. self
may be any object of a class that inherits from MyForm
. Python does not silently create a new superclass object for calling inherited methods, it just passes the same object (doing so would break polymorphism and serve no use). And the type()
/.__class__
is obviously the class the object is really an instance of, not some superclass of that (you don't expect MyShinyThing().__class__
to yield object
, right?). It would be really astonishing, non-idiomatic and useless if __class__
changed depending on where it is accessed from. It's just polymorphism.
And as the first argument to super
is an indicator where in the MRO the search for a supermethod should continue (informally: where you currently are), passing self.__class__
always starts back at the (immediate) superclass of whatever class self
is an instance of. Assuming proper super
calls elsewhere in the class hierarchy, this ultimately gets you back to MyForm.process
, and we've got our infinite loop.