473,394 Members | 1,277 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,394 software developers and data experts.

Method resolution for super(Class, obj).

Hello everybody.

Consider the following code:
class A(object):
def met(self):
print 'A.met'
class B(A):
def met(self):
print 'B.met'
super(B,self).met()
class C(A):
def met(self):
print 'C.met'
super(C,self).met()
class D(B,C):
def met(self):
print 'D.met'
super(D,self).met()
d = D()
d.met()
When executed, it prints:

D.met
B.met
C.met
A.met

The book (Python in a nutshell, 2nd edition) explains:

"The solution is to use built-in type super. super(aclass, obj),
which returns a special superobject of object obj. When we look
up an attribute (e.g., a method) in this superobject, the lookup
begins after class aclass in obj's MRO."

But I don't understand - MRO means that when attribute is found
somewhere in hierarchy, the search for it stops, that is: when
d.met() is executed, it is supposed to print 'D met', call
super(D,self).met() which should resolve met() to be B's attribute,
and after B's met() is executed, we should be done. Why does the
lookup proceeds from B to C as though met() wasn't found in B?
Indeed, lookup order (according to a new-style MRO) is B, then C
and at last A (because of a diamond inheritance), but only when
attribute is not found in B it is looked up in C, and only if it
is not found neither in B nor in C it is looked up in A...

What is different here?

ddtl.
Sep 7 '06 #1
4 1699

ddtl wrote:
Hello everybody.

Consider the following code:
class A(object):
def met(self):
print 'A.met'
class B(A):
def met(self):
print 'B.met'
super(B,self).met()
class C(A):
def met(self):
print 'C.met'
super(C,self).met()
class D(B,C):
def met(self):
print 'D.met'
super(D,self).met()
d = D()
d.met()
When executed, it prints:

D.met
B.met
C.met
A.met

The book (Python in a nutshell, 2nd edition) explains:

"The solution is to use built-in type super. super(aclass, obj),
which returns a special superobject of object obj. When we look
up an attribute (e.g., a method) in this superobject, the lookup
begins after class aclass in obj's MRO."

But I don't understand - MRO means that when attribute is found
somewhere in hierarchy, the search for it stops, that is: when
d.met() is executed, it is supposed to print 'D met', call
super(D,self).met() which should resolve met() to be B's attribute,
and after B's met() is executed, we should be done. Why does the
lookup proceeds from B to C as though met() wasn't found in B?
Indeed, lookup order (according to a new-style MRO) is B, then C
and at last A (because of a diamond inheritance), but only when
attribute is not found in B it is looked up in C, and only if it
is not found neither in B nor in C it is looked up in A...

What is different here?
Let's examine what the mro order is for class D:
>>D.mro()
[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>,
<class '__mai
n__.A'>, <type 'object'>]

When you call d.met(), the call dispatches to the D.met() method.
After printing out 'D.met', you use super() to get the next class in
the mro order, and call that class's met method.

As shown with the mro(), the class after D is B. So B.met() is called.
Normally, we would be done. But take a look at B's method!
class B(A):
def met(self):
print 'B.met'
super(B,self).met()
B.met calls super, and invokes the next met method! So, the code does
exactly what you've asked it to do, and searches for the next class
after B in the mro list: class C. You are then invoking met method of
that class. So, class B is calling class C's met method.

Class C also uses super, and calls the resulting met method on the
result as well. This finds class A as the next class in the mro list,
and invokes the met method on it as well.

When you get to A's met method, you aren't calling another met method,
so the print statements end.

If you want the dispatch to end at B's method, comment out the
'super(B,self).met()' line:
>>class B2(A):
.... def met(self):
.... print 'B2.met'

Alternatively, you could do away with using super entirely, and
actively call the superclass method that you want:
>>class D2(B2, C):
.... def met(self):
.... print 'D2.met'
.... B2.met(self) # Invoke B2's method directly
....
>>d2 = D2()
d2.met()
D2.met
B2.met

You don't need super() to call a superclass method. It can help with
complex class heirarchies, but most single-descendent class structures
don't need it. Either way, when designing a class heirarchy, you
should either always use super() or never use super(). Mixing
non-super-using and super-using can give you problems.

(Rhetorical Q: Does this make me more or less super?)

--Jason

Sep 7 '06 #2
On 7 Sep 2006 10:42:54 -0700, in comp.lang.python you wrote:
>Let's examine what the mro order is for class D:
>>>D.mro()
[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>,
<class '__mai
n__.A'>, <type 'object'>]

When you call d.met(), the call dispatches to the D.met() method.
After printing out 'D.met', you use super() to get the next class in
the mro order, and call that class's met method.

As shown with the mro(), the class after D is B. So B.met() is called.
Normally, we would be done. But take a look at B's method!
>class B(A):
def met(self):
print 'B.met'
super(B,self).met()

B.met calls super, and invokes the next met method! So, the code does
exactly what you've asked it to do, and searches for the next class
after B in the mro list: class C.
But when super(B,self).met() is invoked, isn't it supposed to look
at MRO order of *B*, which is:

(<class '__main__.B'>, <class '__main__.A'>, <type 'object'>)

and B doesn't have any relation with C, that is: A's met() is the to
be called as a result. In effect, what you say impies that a call to
super() is context dependant - if super(B,self).met() is invoked as
a result of a call to D().met(), the effect is different from the effect
of a call to B().met(). But a documentation of a super() doesn't mention
anything like that (or at least I didn't find it), and it seems a
significant piece of information. Doesn't it imply that there should
be another explanation?

ddtl.
Sep 7 '06 #3
ddtl wrote:
On 7 Sep 2006 10:42:54 -0700, in comp.lang.python you wrote:

>>Let's examine what the mro order is for class D:
>>>>>D.mro()

[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>,
<class '__mai
n__.A'>, <type 'object'>]

When you call d.met(), the call dispatches to the D.met() method.
After printing out 'D.met', you use super() to get the next class in
the mro order, and call that class's met method.

As shown with the mro(), the class after D is B. So B.met() is called.
Normally, we would be done. But take a look at B's method!

>>>class B(A):
def met(self):
print 'B.met'
super(B,self).met()

B.met calls super, and invokes the next met method! So, the code does
exactly what you've asked it to do, and searches for the next class
after B in the mro list: class C.


But when super(B,self).met() is invoked, isn't it supposed to look
at MRO order of *B*, which is:

(<class '__main__.B'>, <class '__main__.A'>, <type 'object'>)
No, that's the mistake people often make. An instance of type B would
see B's MRO, but an instance of type D sees D's MRO.
and B doesn't have any relation with C, that is: A's met() is the to
be called as a result. In effect, what you say impies that a call to
super() is context dependant - if super(B,self).met() is invoked as
a result of a call to D().met(), the effect is different from the effect
of a call to B().met(). But a documentation of a super() doesn't mention
anything like that (or at least I didn't find it), and it seems a
significant piece of information. Doesn't it imply that there should
be another explanation?
It's all rather better explained in the Nutshell Guide than it is in the
Python documentation. But basically you've got it right: it's the class
of the *instance* that determines the MRO used by super().

regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://holdenweb.blogspot.com
Recent Ramblings http://del.icio.us/steve.holden

Sep 7 '06 #4
ddtl a écrit :
On 7 Sep 2006 10:42:54 -0700, in comp.lang.python you wrote:

>>Let's examine what the mro order is for class D:
>>>>>D.mro()

[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>,
<class '__mai
n__.A'>, <type 'object'>]

When you call d.met(), the call dispatches to the D.met() method.
After printing out 'D.met', you use super() to get the next class in
the mro order, and call that class's met method.

As shown with the mro(), the class after D is B. So B.met() is called.
Normally, we would be done. But take a look at B's method!

>>>class B(A):
def met(self):
print 'B.met'
super(B,self).met()

B.met calls super, and invokes the next met method! So, the code does
exactly what you've asked it to do, and searches for the next class
after B in the mro list: class C.


But when super(B,self).met() is invoked, isn't it supposed to look
at MRO order of *B*,
No. It's supposed to look at the MRO of self for what comes after B.

Sep 10 '06 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Fernando Rodriguez | last post by:
Hi, I need to traverse the methods defined in a class and its superclasses. This is the code I'm using: # An instance of class B should be able to check all the methods defined in B #and A,...
7
by: Robin Forster | last post by:
I have two classes: aule_gl_window (parent class) and aule_button (sub class) I want to call the super class (parent) constructor code from the sub class constructor.
5
by: Da Costa Gomez | last post by:
Hi, I was wondering whether someone could shed some light on the following. Using inheritance in Java one can override a function f() (or is it overload?) in the child and then do: public f() {...
8
by: Snyke | last post by:
Ok this is a bit fishy actually: I have a class (a socket wrapper) which reads some data from a stream and then should respond to it. This is done in two function (OnRead, which reads from the...
1
by: Martin | last post by:
Hi, I've got a base/super class with just a default constructor. I want another constructor, but I can't modify the base class, so I created a sub class with a constructor like so: public...
2
by: Wilson | last post by:
Hi, How can I call the super class in c# ? e.g. protected void Page_Load(object sender, EventArgs e) { call the super class ??? }
1
by: UptownYardy | last post by:
Hi excuse the mistake in the title. I'm having trouble on inheriting methods from a superclass in Java. Basically I've forgotten how to. I want to inherit 3 methods from the Artwork superclass to...
3
by: Marc | last post by:
How would you explicitly call a method of a 'super' class in C#? What do I put at the dots to just call the GetHierarchicalView of XmlDataSource? public class XmlDataSourceMarc : XmlDataSource...
3
by: MiziaQ | last post by:
how can i call a gui component (contentPane) from a super class to a different class ? Code would be appreciated. Thanks in advance
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.