[Python-Dev] super() (original) (raw)
Guido van Rossum guido@python.org
Fri, 24 Aug 2001 13:09:37 -0400
- Previous message: [Python-Dev] Comments2: PEP 252, PEP 253 and jython issues
- Next message: [Python-Dev] Re: [Python-checkins] CVS: python/dist/src/Python bltinmodule.c,2.227,2.228
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Thomas Heller wrote (in private email, responding to a checkin message):
From: "Guido van Rossum" <gvanrossum@users.sourceforge.net> > Add 'super', another new object type with magical properties. > > super(type) -> unbound super object > super(type, obj) -> bound super object; requires isinstance(obj, type) > > Typical use to call a cooperative superclass method: > > class C(B): > def meth(self, arg): > super(C, self).meth(arg);
Shouldn't that be class C(B): def meth(self, arg): super(B, self).meth(arg) ^ to call B.meth(self, arg)? Thomas
No. Good question, though! You have to pass your own class so that this finds the right super-method when multiple inheritance involving a "diamond" diagram. You may want to read the section on Method resolution order in PEP 253 first.
Look at this example:
class A(object):
def meth(self, a):
return "A.meth(%r)" % a
print A().meth(1)
class B(A):
def __init__(self):
self.__super = super(B, self)
def meth(self, a):
return "B.meth(%r) -> " % a + self.__super.meth(a)
print B().meth(2)
class C(A):
__dynamic__ = 1
def meth(self, a):
return "C.meth(%r) -> " % a + self.__super.meth(a)
C._C__super = super(C)
print C().meth(3)
class D(C, B):
def meth(self, a):
return "D.meth(%r) -> " % a + super(D, self).meth(a)
print D().meth(4) # D.meth(4) -> C.meth(4) -> B.meth(4) -> A.meth(4)
D has the following inheritance graph:
A
^ ^
/ \
/ \
/ \
/ \
C B
^ ^
\ /
\ /
\ /
\ /
D
When you have a C or B instance, C.meth's super references A. But when you have a D instance, C.meth's super references B!
In other words, D.meth calls C.meth calls B.meth calls A.meth. This is why you need to pass self to super() -- it needs the mro sequence of the instance. Remember that D.mro == (D,C,B,A,object). C.meth calls super(C, D()).meth. This looks for C in D.mro, and then starts searching for meth at the next class -- finding B.meth.
If you wonder why the MRO is designed this way, imagine that meth() does some sort of saving to disk. Each subclass saves its own stuff and then calls the save method of its base class. Without the behavior described above, D.save() would have to call C.save() and B.save(), but this would call A.save() twice!
This is part of a pattern called cooperative class design, described in the book Putting Metaclasses to Work (for a reference, see PEP 253).
--Guido van Rossum (home page: http://www.python.org/~guido/)
- Previous message: [Python-Dev] Comments2: PEP 252, PEP 253 and jython issues
- Next message: [Python-Dev] Re: [Python-checkins] CVS: python/dist/src/Python bltinmodule.c,2.227,2.228
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]