2

Suppose I have two classes in Python as below:

class Parent(object):
    def __init__(self):
        self.num = 0

    def fun1(self):
        print 'p.fun1'

    def fun2(self):
        self.fun1()
        print 'p.fun2'

and

from parent import Parent

class Child(Parent):
    def __init__(self):
        super(Child,self).__init__()

    def fun1(self):
        print 'c.fun1'

    def fun2(self):
        super(Child, self).fun2()
        print 'c.fun2'

and if I call fun2 of Child

from child import Child

test = Child()
test.fun2()

I get output:

c.fun1
p.fun2
c.fun2

Which means the call of Child.fun2() leads to Parent.fun2(). But inside the Parent.fun2(), I use self.fun1() which in this case interpreted as Child.fun1() in my test.

But I really want the class Parent to be individual and the call of Parent.fun2() always uses Parent.fun1() inside it.

How can I avoid this?

I only know that I can make Parent.fun1() private into Parent.__fun1(). But I also have some instances of Parent where I need to use Parent.fun1() outside this class. That means I really need to override the fun1().

5
  • It's a bit unclear what you mean. An instance of Parent will always call Parent.fun1, and an instance of Child will always call Child.fun1. Commented Apr 7, 2017 at 8:34
  • sorry for my unclearance. I want that: In the class Parent any uses of self.fun1() only refer to Parent.fun1(). In my test, since I create an instance of Child, the use of Child.fun2() lead to Parent.fun2(). And this call for Parent.fun2() calls for Child.fun1(), but I want it to call for Parent.fun1(). I hope the output become p.fun1 p.fun2 c.fun2 Commented Apr 7, 2017 at 8:41
  • 1
    Then why do you implement fun1 in the child class? Commented Apr 7, 2017 at 9:19
  • BTW, it's redundant to define a method in a derived class if all it does is call super, since that happens automatically if the method doesn't exist in the derived class. So you can get rid of the __init__ in Child. Commented Apr 7, 2017 at 9:40
  • Thank you for your interests in my question. These codes are just a really simplified exemple of the problem I have encountered. For the fun1 in child class, I may need pass all data through a filter and do the same computation of fun1 in parent class. Surely, I won't override a method with just a super() ;) Commented Apr 10, 2017 at 13:10

2 Answers 2

2

That's how inheritance is supposed to work. For the behavior you need, you might want to reconsider Parent & Child class's relationship, or change the method names or at least make the Parent methods classmethods or staticmethods.

This should work for your need, but I don't really like it.

class Parent(object):
    def __init__(self):
        self.num=0
    def fun1(self):
        print 'p.fun1'
    def fun2(self):
        Parent.fun1(self)
        print 'p.fun2'

Child class can remain the same.

In all classes accessed in the inheritance chain, self will always point to the instance of class actually instantiated and not the current class accessed in super call (or in order to find method/attribute for that matter). So self.fun2 will always point to the method of Child class.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for you answer! It's much more clear for me ;)
1

There is a mechanism called Name Mangling:

Any identifier of the form __spam (at least two leading underscores, at most one trailing underscore) is textually replaced with _classname__spam, where classname is the current class name with leading underscore(s) stripped. This mangling is done without regard to the syntactic position of the identifier, as long as it occurs within the definition of a class. Name mangling is helpful for letting subclasses override methods without breaking intraclass method calls Python Classes Documentation

This should work:

class Parent(object):
    def __init__(self):
    self.num = 0

    def fun1(self):
        print 'p.fun1'

    def fun2(self):
        self.__fun1()
        print 'p.fun2'

    __fun1 = fun1

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.