Updated blog post on how to use super()

  • Thread starter Raymond Hettinger
  • Start date
R

Raymond Hettinger

I've tightened the wording a bit, made much better use of keyword
arguments instead of kwds.pop(arg), and added a section on defensive
programming (protecting a subclass from inadvertently missing an MRO
requirement). Also, there is an entry on how to use assertions to
validate search order requirements and make them explicit.

http://bit.ly/py_super
or
http://rhettinger.wordpress.com/2011/05/26/super-considered-super/

Any further suggestions are welcome. I'm expecting this to evolve
into how-to guide to be included in the regular Python standard
documentation. The goal is to serve as a reliable guide to using
super and how to design cooperative classes in a way that lets
subclasses compose and extent them.


Raymond Hettinger
 
B

Billy Mays

I've tightened the wording a bit, made much better use of keyword
arguments instead of kwds.pop(arg), and added a section on defensive
programming (protecting a subclass from inadvertently missing an MRO
requirement). Also, there is an entry on how to use assertions to
validate search order requirements and make them explicit.

http://bit.ly/py_super
or
http://rhettinger.wordpress.com/2011/05/26/super-considered-super/

Any further suggestions are welcome. I'm expecting this to evolve
into how-to guide to be included in the regular Python standard
documentation. The goal is to serve as a reliable guide to using
super and how to design cooperative classes in a way that lets
subclasses compose and extent them.


Raymond Hettinger

I read this when it was on HN the other day, but I still don't see what
is special about super(). It seems (from your post) to just be a stand
in for the super class name? Is there something special I missed?
 
I

Ian Kelly

I read this when it was on HN the other day, but I still don't see what is
special about super().  It seems (from your post) to just be a stand infor
the super class name?  Is there something special I missed?

It's not a stand-in for the super-class name. It's a stand-in for
whatever class is next in the Method Resolution Order (MRO), which is
determined at run-time and can vary depending on what the actual class
of the object is. For example, in this inheritance situation:

class A(object):
...

class B(object):
...

class C(A, B):
...

a = A()
c = C()

The MRO of A is (A, object).
The MRO of B is (B, object).
The MRO of C is (C, A, B, object).

Thus, super(A, a) is going to resolve to object, as you might expect.
But super(A, c) is going to resolve to B, because the next class after
A in the MRO for C instances is B.

That's a pretty quick and dirty explanation. If it doesn't make
sense, I suggest reading the article again.
 
B

Billy Mays

It's not a stand-in for the super-class name. It's a stand-in for
whatever class is next in the Method Resolution Order (MRO), which is
determined at run-time and can vary depending on what the actual class
of the object is. For example, in this inheritance situation:

class A(object):
...

class B(object):
...

class C(A, B):
...

a = A()
c = C()

The MRO of A is (A, object).
The MRO of B is (B, object).
The MRO of C is (C, A, B, object).

Thus, super(A, a) is going to resolve to object, as you might expect.
But super(A, c) is going to resolve to B, because the next class after
A in the MRO for C instances is B.

That's a pretty quick and dirty explanation. If it doesn't make
sense, I suggest reading the article again.

What it does is clear to me, but why is it interesting or special isn't.
This looks like a small feature that would be useful in a handful of
cases.
 
I

Ian Kelly

What it does is clear to me, but why is it interesting or special isn't.
 This looks like a small feature that would be useful in a handful of cases.

Well, I agree with you there. The complexity introduced by super
typically outweighs the benefits it provides, IMO. The only time when
it is really necessary is in non-trivial diamond inheritance
situations (to avoid calling the same method on some base class more
than once), and in those cases I think it is simply better to not use
multiple inheritance in the first place.

Cheers,
Ian
 
C

Chris Torek

Summary: super(cls, data) in a method gets you the "next" handler
for a given class "cls" and an instance "data" that has derived
from that class at some point. In Python 2 you must spell out the
names of the class and instance (normally "self") explicitly, while
Python 3 grabs, at compile time, the class from the lexically
enclosing class, and the instance from the first argument of the
method that invokes "super".

The "next" handler depends on the instance's __mro__. If all
your classes use at most single inheritance, the "next" handler
in class Cls1 is easy to predict:

class Cls1(Cls2):

Any instance of Cls1 always has Cls2 as its "next", so:

def method(self, arg1, arg2):
...
Cls2.method(self, arg1_mutated, arg2_mutated)
...

works fine. But if you use multiple inheritance, the next method
is much harder to predict. If you have a working "super", you
can use:

super().method(self, arg1_mutated, arg2_mutated)

and it will find the correct "next method" in all cases.

What it does is clear to me, but why is it interesting or special isn't.
This looks like a small feature that would be useful in a handful of
cases.

Indeed: it is useful when you have multiple inheritance, which for
most programmers, is a "handful of cases".

However, provided you *have* the Py3k super() in the first place,
it is also trivial and obviously-correct to write:

super().method(...)

whereas writing:

NextClass.method(...)

requires going up to the class definition to make sure that
"NextClass" is indeed the next class, and hence -- while usually
no more difficult to write -- less obviously-correct.

Moreover, if you write the easy-to-write obviously-correct
"super().method", *your* class may now be ready for someone
else to use in a multiple-inheritance (MI) situation. If you type
in the not-as-obviously-correct "NextClass.method", *your* class
is definitely *not* ready for someone else to use in that MI
situation.

(I say "may" be ready for MI, because being "fully MI ready" requires
several other code discipline steps. The point of super() -- at
least when implemented nicely, as in Py3k -- is that it makes it
easy -- one might even say "super easy" :) -- to write your code
such that it is obviously correct, and also MI-friendly.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,575
Members
45,053
Latest member
billing-software

Latest Threads

Top