Why does super take a class name as the argument?

  • Thread starter Scott David Daniels
  • Start date
S

Scott David Daniels

Chris said:
... I can't find any
discussion of why super needs the name of the class as an argument.

super(self).method() seems like super could just do the right
thing...
It could "just do the right thing", but not as a function, only as a
compiler magic thingamiebob. When methods are being translated, they
are ordinary function definitions, and the class for which they will
become a method does not exist. By including the name of the class
itself, rather than the name of the (or a) super class, super can search
in the "mro" for the class, and find the next class in that order after
the given class. "super" seems to me to have the "explicit is better
than implicit" flavor without forcing you to know the whole inheritance
structure.

-Scott David Daniels
(e-mail address removed)
 
C

Chris Green

Good day,

I've done a bit of searching in the language reference and a couple
pages referring the behavior of super() but I can't find any
discussion of why super needs the name of the class as an argument.
Feel free to point me into the bowels of google if this has been
discussed to death already.

super(self).method() seems like super could just do the right
thing...

super(kls).method() could also work if you needed access up the tree
to from a classmethod. Maybe I'm missing something with Metaclasses.

The reason I'm asking about this is I find myself cursing super every
time I want to change the name of the class I'm working on when one of
the reason's that super was implemented (I'm guessing) was to insulate
derived classes from the name changes of where they inherited from.

Thanks,
Chris
 
S

Sion Arrowsmith

Chris Green said:
I've done a bit of searching in the language reference and a couple
pages referring the behavior of super() but I can't find any
discussion of why super needs the name of the class as an argument.

http://www.python.org/2.2.1/descrintro.html#mro and
http://www.python.org/2.2.1/descrintro.html#cooperation
super(self).method() seems like super could just do the right
thing...

super(kls).method() could also work if you needed access up the tree
to from a classmethod. Maybe I'm missing something with Metaclasses.

To try and summarise (and grossly simplify), consider:

class A(object):
def method(self):
pass

class B(A):
def method(self):
super(B, self).method()

class C(A):
def method(self):
super(C, self).method()

class D(B, C):
def method(self):
super(A, self).method()

If super worked just off self, how are the method()s in B and C
supposed to know that they should be calling A.method() (since
isinstance(self, D))? If super worked just off the class, both
B.method() and C.method() would call A.method() when called
from D.method(). So super needs to know both the class of self
and the class the method it is being used from belongs to. And
if you think the latter is easy for the compiler, consider

def generic_method(self):
...

B.method = generic_method
 
S

Shalabh Chaturvedi

Chris Green wrote:
.. . .
The reason I'm asking about this is I find myself cursing super every
time I want to change the name of the class I'm working on when one of
the reason's that super was implemented (I'm guessing) was to insulate
derived classes from the name changes of where they inherited from.

Derived classes *are* insulated from name changes of the base classes.
The class in super has to be the same as the class in which the super
call is written (i.e. the one 'around' the super call), not a base
class. So if you change a class name, you only change the super calls
that exist within that class.

Of course, it could be easier with more support from the interpreter
(and it may be in a future version). See also autosuper in Guido's essay [1]

Shalabh

[1] http://www.python.org/2.2.3/descrintro.html
 
L

Leif K-Brooks

Chris said:
I've done a bit of searching in the language reference and a couple
pages referring the behavior of super() but I can't find any
discussion of why super needs the name of the class as an argument.

Think about it. In this code:

class A(object):
def do_stuff(self):
print "A is doing stuff now."


class B(A):
def do_stuff(self):
super(B, self).do_stuff()
print "B is doing stuff now."


class C(B):
def do_stuff(self):
super(C, self).do_stuff()
print "C is doing stuff now."


How would Python know that B should call C's do_stuff() method instead
of its own if there was no class argument? The self argument would be
exactly the same when C called super() as when B called it. There has
been some talk of making super into a language keyword instead of a
type, though; that would eliminate the need to even pass in self.
 
D

dataangel

Leif said:
Think about it. In this code:

class A(object):
def do_stuff(self):
print "A is doing stuff now."


class B(A):
def do_stuff(self):
super(B, self).do_stuff()
print "B is doing stuff now."


class C(B):
def do_stuff(self):
super(C, self).do_stuff()
print "C is doing stuff now."


How would Python know that B should call C's do_stuff() method instead
of its own if there was no class argument? The self argument would be
exactly the same when C called super() as when B called it. There has
been some talk of making super into a language keyword instead of a
type, though; that would eliminate the need to even pass in self.

What's the going argument against it? Makes sense to me.
 
E

Ed Leafe

What's the going argument against it? Makes sense to me.

There are constructions in other languages whereby an call to the
superclass method does not require an explicit name of the current
class. When an inherited method is augmented in a subclass, the call to
the superclass version of the method doesn't require any class
specification; each class knows its own hierarchy.

So in the examples others have given, you'd have:

class A(object):
def theMethod(self):
print "doing A stuff"

def someOtherMethod(self):
print "Some Other A method is running"

class B(A):
def theMethod(self):
print "doing some early B stuff"
self.super()
print "some final B stuff"

When B is created and its theMethod() is called, it prints as follows:
doing some early B stuff
doing A stuff
some final B stuffSome Other A method is running

In other words, the B class knows it inherits from the A class. When
the call to super() is encountered, B looks to its superclass for such
a method, and executes it if found. If it has multiple parents, it is
resolved as is normally done with multiple inheritance. When the call
to someOtherMethod() is made, the B object knows that it should execute
that method is its superclass.

Think of it another way: since B can figure out how to execute a call
to a method that doesn't exist in B itself by looking into its class
hierarchy, why can't a call like self.super() execute the code that
would have been executed had the subclass not overridden the method in
the first place?

___/
/
__/
/
____/
Ed Leafe
http://leafe.com/
http://dabodev.com/
 
G

Glenn Andreas

Ed Leafe said:
There are constructions in other languages whereby an call to the
superclass method does not require an explicit name of the current
class. When an inherited method is augmented in a subclass, the call to
the superclass version of the method doesn't require any class
specification; each class knows its own hierarchy.

Except that in python a method can be changed to a different class, or
even multiple classes, not to mention the fact that class parents can be
dynamically reassigned.

In lanagues like Self, which is similar in its flexibility (but can
actually handle this sort of thing), the method itself inherits from the
object (it's kind of confusing to wrap your head around) so it can
figure out things like this, but Python doesn't work that way.

Think of it another way: since B can figure out how to execute a call
to a method that doesn't exist in B itself by looking into its class
hierarchy, why can't a call like self.super() execute the code that
would have been executed had the subclass not overridden the method in
the first place?

When an instance "b" (or say "c" which is an instance of class "C" which
is a subclass of "B") executes something like "self.foo", it starts
looking at the class of self. "super" actually starts further up the
chain - if self is "c", you want "A.foo" and not "B.foo" (which is what
you'd get if it tried to derive who "super" is based on "self").
 
M

Michele Simionato

Chris Green said:
Good day,

I've done a bit of searching in the language reference and a couple
pages referring the behavior of super() but I can't find any
discussion of why super needs the name of the class as an argument.
Feel free to point me into the bowels of google if this has been
discussed to death already.

Others have already answered your question. I want just to point out
that there exists recipes to avoid retyping the class name: the first
of these is Guido's autosuper recipe. A very sophysticated one is this one:

http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/286195

I also wrote one of such recipes -;)

http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/284528

Michele Simionato
 

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

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,528
Members
45,000
Latest member
MurrayKeync

Latest Threads

Top