What are super()'s semantics?
Maric Michaud
maric at aristote.info
Mon Sep 4 07:53:23 EDT 2006
Le lundi 04 septembre 2006 12:25, Mike Krell a écrit :
> 1. The super() call in D somehow invokes both parent class methods
> instead of stopping when the method is resolved in B. This has
> nothing to do with truncated lookup per se. Why isn't the output "D
> B A"?
>
Yes but, super(B, B()) and super(B,D()) are not the same object like the code
below shows.
> 2. If I understand correctly, B's MRO is (B, A) and super(B, self) would
> have an MRO of (A). Similarly for C. So it seems that by the above
> explanation, A.met() would still be invoked twice (assuming both
> B.met() and C.met() are invoked).
super(class_, self), is an instance of super, so its class, "super", have a
mro of [<type 'super'>, <type 'object'>]....
"self" in each method call is the same and indeed its type's mro doesn't
change !
-- In [80]: class A(object) :
....: def sup(self) :
....: print 'A'
....:
....:
In [81]: class B(A) :
....: def sup(self) :
....: print 'B'
....: s(B, self).sup()
....:
....:
In [82]: class C(A) :
....: def sup(self) :
....: print 'C'
....: s(C, self).sup()
....:
....:
In [83]: class D(B,C) :
....: def sup(self) :
....: print 'D'
....: s(D, self).sup()
....:
....:
In [97]: class s(super) :
....: def __new__(*a) :
....: print a
....: return super.__new__(*a)
....:
....:
In [98]: D().sup()
D
(<class '__main__.s'>, <class '__main__.D'>, <__main__.D object at
0xa763186c>)
B
(<class '__main__.s'>, <class '__main__.B'>, <__main__.D object at
0xa763186c>) <--- instance is always the same !!
C
(<class '__main__.s'>, <class '__main__.C'>, <__main__.D object at
0xa763186c>) <--- instance is always the same !!
A
In [100]: super(B, D()).sup()
C
(<class '__main__.s'>, <class '__main__.C'>, <__main__.D object at
0xa763178c>)
A
This shows that C is called following the mro of type(D()) from class B to top
and not the mro of B.
All the magic is in the __getattribute__ of super which retrieve the
following class in the mro given its argument.
In [140]: class A(object) :
.....: def sup(self) : print 'a'
.....:
.....:
In [141]: class B(A) :
.....: def sup(self) : print 'b'
.....:
.....:
In [142]: class C(A) :
.....: def sup(self) : print 'c'
.....:
.....:
In [143]: class D(B,C) : pass
.....:
In [147]: super.__getattribute__(super(D,D()), 'sup')()
b
In [148]: super.__getattribute__(super(B,D()), 'sup')()
c
In [149]: super.__getattribute__(super(C,D()), 'sup')()
a
Hope this is clear.
_____________
Maric Michaud
_____________
Aristote - www.aristote.info
3 place des tapis
69004 Lyon
Tel: +33 426 880 097
More information about the Python-list
mailing list