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/)
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4