3 ms·
> That is also true if you attach the method to the class (C.foo = B.foo); you can call it like a method, but super() still checks the type and will complain.
by pansa2 7y ago
> That is also true if you attach the method to the class (C.foo = B.foo); you can call it like a method, but super() still checks the type and will complain.
You're right. Here's some example Python code:
>>> class A:
... def foo(self):
... print('A.foo')
>>> class B(A):
... def foo(self):
... super().foo()
... print('B.foo')
>>> b = B()
>>> b.foo()
A.foo
B.foo
>>> class C:
... def foo(self):
... print('C.foo')
>>> class D(C):
... def foo(self):
... super().foo()
... print('D.foo')
>>> d = D()
>>> d.foo()
C.foo
D.foo
Now, if I do `D.foo = B.foo` and call `d.foo()`, I do indeed get a "TypeError: super(type, obj): obj must be an instance or subtype of type". That's better than getting `A.foo B.foo`, as happens in JavaScript.
However, if `super` were truly dynamic, I would have expected to get `C.foo B.foo`.
- blattimwind 7y agoIIRC super() is actually syntactic sugar for super(ClassTheDefIsFoundIn, nameOfFirstArgument), because there is no way I can think of to implement that as a function at runtime.
- pansa2 7y agoYes, I think that’s right. However, I think it would work better if classTheDefIsFoundIn were resolved dynamically rather than lexically. Perhaps it would have been possible to do this by modifying the descriptor protocol?
- blattimwind 7y agoI'm not sure that's possible, because you could only work with type(self), and that breaks MRO traversal. (A chain of super().x() calls in a hierarchy like A->B->C would always call the first parent class, because it has no way to tell >where< in the hierarchy it is. That's the reason why the class argument is required.) I think that would need an entirely differently designed mechanism and can't be bolted on.