grandparent method with super

K

kyosohma

Hi,

I have a class structure as follows and I would like to invoke the
method A.m() from D.m

class A(object):
def m(self):
class B(A):
def m(self):
class C(A):
def m(self):
class D(B,C):
def m(self):
# Call A.m with super?

I have readhttp://www.python.org/download/releases/2.2/descrintro/but
I am still stuck.

Thanks in advance

Martin

I'm not sure if this is what you want, but it's my best guess:

class A(object):
def m(self):
print "I'm the original"
class B(A):
def m(self):
print 'B class here'
class C(A):
def m(self):
print 'C class here'
class D(B,C):
def m(self):
x = A()
x.m()

temp = D()
temp.m()



Mike
 
J

John Clark

Pretty sure you can do this:

class A(object):
def m(self):
class B(A):
def m(self):
class C(A):
def m(self):
class D(B,C):
def m(self):
A.m(self)

I don't think you want to try to use super() in this case.

-jdc

-----Original Message-----
From: [email protected]
[mailto:p[email protected]] On Behalf Of Martin
Manns
Sent: Thursday, April 05, 2007 4:20 PM
To: (e-mail address removed)
Subject: grandparent method with super

Hi,

I have a class structure as follows and I would like to invoke the method
A.m() from D.m

class A(object):
def m(self):
class B(A):
def m(self):
class C(A):
def m(self):
class D(B,C):
def m(self):
# Call A.m with super?

I have read http://www.python.org/download/releases/2.2/descrintro/ but I am
still stuck.

Thanks in advance

Martin
 
M

Martin Manns

Pretty sure you can do this:

class A(object):
def m(self):
class B(A):
def m(self):
class C(A):
def m(self):
class D(B,C):
def m(self):
A.m(self)

I don't think you want to try to use super() in this case.

That works, but when I replace A with something else, I do not get the
grandparent anymore without changing all the method calls. Basically, I
would like to call the method m in the first grandparent of D.

Martin
 
J

John Clark

That works, but when I replace A with something else, I do not get the grandparent anymore
without changing all the method calls. Basically, I would like to call the method m in the first
grandparent of D.

Martin

I think the problem you may run into is with the term "first grandparent" -
when you look at the method resolution order of the class D, you will find
that the MRO goes "D, C, B, A"... I think it's going to be difficult to
figure out where the "first grandparent" is in the MRO.

For example:

class A(object):
def m(self):
pass
class B(A):
def m(self):
pass
class C(B):
def m(self):
pass
class D(A):
def m(self):
pass
class E(C,D):
def m(self):
firstgrandparent(E,self).m() #Should call B.m
class F(D,C):
def m(self):
firstgrandparent(F,self).m() # Should call F.m


The mro for class E is going to be "E,C,B,D,A" where as the mro for class F
is going to be "F,D,C,B,A". However, the first grandparent for E should be
B, where as the first grandparent for F should be A.

Because the MRO isn't just a depth first traversal, the term "first
grandparent" gets tricky to define...

-jdc
 
M

Martin Manns

I think the problem you may run into is with the term "first
grandparent" - when you look at the method resolution order of the
class D, you will find that the MRO goes "D, C, B, A"... I think it's
going to be difficult to figure out where the "first grandparent" is
in the MRO.

For example:

class A(object):
def m(self):
pass
class B(A):
def m(self):
pass
class C(B):
def m(self):
pass
class D(A):
def m(self):
pass
class E(C,D):
def m(self):
firstgrandparent(E,self).m() #Should call B.m
class F(D,C):
def m(self):
firstgrandparent(F,self).m() # Should call F.m


The mro for class E is going to be "E,C,B,D,A" where as the mro for
class F is going to be "F,D,C,B,A". However, the first grandparent
for E should be B, where as the first grandparent for F should be A.

Because the MRO isn't just a depth first traversal, the term "first
grandparent" gets tricky to define...

Not really. The first grandparent would be the first occurrence in the
list from left to right, which satisfies the requirement that its
shortest path to the current class is 2.

The only problem: How do I get it?

Martin
 
G

Gabriel Genellina

On Thu, 5 Apr 2007 16:55:38 -0400


Not really. The first grandparent would be the first occurrence in the
list from left to right, which satisfies the requirement that its
shortest path to the current class is 2.
The only problem: How do I get it?

Calling super() twice? F.mro()[1]? But really I don't think it's a good
idea - depending on the *other* classes in your hierarchy, what you call
"grandparent" may be almost anyone.
If you *have* to bypass your parent, it feels like there is something
wrong in the class hierarchy.
 
A

attn.steven.kuo

Not really. The first grandparent would be the first occurrence in the
list from left to right, which satisfies the requirement that its
shortest path to the current class is 2.

The only problem: How do I get it?

Martin



class E(C,D):
def m(self):
for cls in E.__mro__:
if cls != E and cls not in E.__bases__:
cls.m(self)
break


.... but it's probably better that you
rethink your class hierarchy.
 
J

John Clark

Not really. The first grandparent would be the first occurrence in the
list from left to right, which satisfies the requirement that its shortest
path to the current class is 2.
The only problem: How do I get it?

I suppose you could do a

self.__class__.__bases__[0].__bases__[0]

(With the appropriate error handling buit in..)

But I am not sure if it's a safe assumption to depend on __bases__ returning
the classes in the order you want...

-jdc
 
M

Martin Manns

On 5 Apr 2007 15:05:25 -0700
class E(C,D):
def m(self):
for cls in E.__mro__:
if cls != E and cls not in E.__bases__:
cls.m(self)
break


... but it's probably better that you
rethink your class hierarchy.

After seeing the implications and the solutions, I will.

Thank you everyone for your help

Martin
 
B

Bruno Desthuilliers

(e-mail address removed) a écrit :
(snip)
I'm not sure if this is what you want, but it's my best guess:

class A(object):
def m(self):
print "I'm the original"
class B(A):
def m(self):
print 'B class here'
class C(A):
def m(self):
print 'C class here'
class D(B,C):
def m(self):
x = A()
x.m()

Err... This will call A.m(x), not A.m(self). The correct thing to is:
class D(B,C):
def m(self):
A.m(self)

But this doesn't solve the OP's problem, which is to not hard-code the
concrete base class to call (hence the question about how to do this
using super)
 

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

Similar Threads

Trouble with code 2
"Super()" confusion 7
super() and multiple inheritance failure 9
using super 16
super behavior 1
super() in class defs? 4
Issues with writing pytest 0
Super() function 1

Members online

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,190
Members
46,736
Latest member
zacharyharris

Latest Threads

Top