Reputation: 31
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()
.
Upvotes: 2
Views: 2174
Reputation: 11
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
Upvotes: 1
Reputation: 8287
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.
Upvotes: 2