避免在python中使用父类中的子方法

时间:2017-04-07 08:24:35

标签: python inheritance override

假设我在Python中有两个类,如下所示:

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

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

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

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'

如果我打电话给孩子的fun2

from child import Child

test = Child()
test.fun2()

我得到输出:

c.fun1
p.fun2
c.fun2

这意味着Child.fun2()的来电会导致Parent.fun2()。但是在Parent.fun2()内部,我使用self.fun1(),在这种情况下我的测试中将其解释为Child.fun1()

但我真的希望课程Parent是个人的,而Parent.fun2()的调用总是在其中使用Parent.fun1()

我该如何避免这种情况?

我只知道我可以Parent.fun1()私密进入Parent.__fun1()。但我也有一些Parent的实例,我需要在这个类之外使用Parent.fun1()。这意味着我真的需要覆盖fun1()

2 个答案:

答案 0 :(得分:1)

那继承应该如何运作。对于您需要的行为,您可能需要重新考虑Parent& Child班级关系,或更改方法名称或至少制作Parent方法classmethodsstaticmethods

这应该适合您的需要,但我不是很喜欢它。

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课程可以保持不变。

在继承链中访问的所有类中,self将始终指向实际实例化的类的实例,而不是super调用中访问的当前类(或者为了查找方法/属性)那件事)。因此self.fun2将始终指向Child类的方法。

答案 1 :(得分:0)

有一种名为名称修改的机制:

  

任何形式为__spam的标识符(至少两个前导下划线,至多一个下划线)在文本上被_classname__spam替换,其中classname是当前类名,其中前导下划线被去除。只要不存在标识符的语法位置,就可以进行这种改写,只要它出现在类的定义内即可。   名称修饰有助于让子类覆盖方法而不中断类内方法调用   Python Classes Documentation

这应该有效:

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