如何在Python中从Child类调用和覆盖Parent类方法

时间:2016-03-21 20:03:34

标签: python python-2.7 oop inheritance parent-child

reproduce课程的ResistantVirus方法中,我试图调用reproduce(self, popDensity)课程的SimpleVirus,而不是返回SimpleVirus课程对象,我希望它返回一个ResistantVirus对象。

显然,我也可以重复SimpleVirus.reproduce方法中的一些代码,并在ResistantVirus.reproduce方法中使用相同的实现,但我想知道是否可以调用和覆盖{{1为了避免重复?

SimpleVirus.reproduce

3 个答案:

答案 0 :(得分:2)

看起来copy可以帮助你。

import copy

class Parent(object):
    def __init__(self, a):
        self.a = a

    def copy(self):
        return copy.deepcopy(self)

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

复制方法将携带self所属的类(不一定是父类)。例如:

Child(1,2).copy() # <__main__.Child object at 0x01832E90>

这似乎是你的主要目标。但是,在构建测试的过程中也可能需要付出一些努力。我使用您的示例代码实现了一个不同的解决方案,允许您继承测试。请注意,要求您将病毒传递给关键字参数列表(**kwargs)。示例用法在。

之后给出
import copy, random

class SimpleVirus(object):

    def __init__(self, max_birth_prob, clear_prob):
        self.max_birth_prob = max_birth_prob
        self.clear_prob = clear_prob
        self._tests = [self.simple_test]

    def copy(self):
        return copy.deepcopy(self)

    def simple_test(self, **kwargs):
        return random.random() < self.max_birth_prob * (1 - kwargs['pop_density'])

    def reproduce(self, **kwargs):
        if all(test(**kwargs) for test in self._tests):
            return self.copy()
        raise Exception


class ResistantVirus(SimpleVirus):

    def __init__(self, max_birth_prob, clear_prob, resistances, mut_prob):

        super(ResistantVirus, self).__init__(max_birth_prob, clear_prob)
        self.resistances = resistances
        self.mut_prob = mut_prob
        self._tests.append(self.resistance_test)

    def resistance_test(self, **kwargs):
        return all(drug in self.resistances for drug in kwargs['drug_list'])

以下内容有时会复制,有时会引发Exception

res_virus = ResistantVirus(0.8, 0.2, ['a', 'b', 'c'], 0.1)
res_virus.reproduce(pop_density=0.3, drug_list=['a', 'b'])

请注意,两个类之间没有重要的代码重用。如果你有一个严格的继承链,那么这很好,并且随着你的进展,事情往往会“积累”。但是,如果你要让很多类都继承SimpleVirus,并且其中一些类共享功能,则可能值得查看object composition over inheritance

答案 1 :(得分:0)

使用super来呼叫父类&#39;方法:

class ResistantVirus(SimpleVirus):
    def __init__(self, maxBirthProb, clearProb, resistances, mutProb):
        self.resistances = resistances
        self.mutProb = mutProb
        super(ResistantVirus, self).__init__(maxBirthProb, clearProb)

    def reproduce(self, popDensity):
        simple_virus = super(ResistantVirus, self).reproduce(popDensity)
        resistances = # TODO
        mutProb = # TODO
        return ResistantVirus(simple_virus.maxBirthProb,
                              simple_virus.clearProb, 
                              resistances, 
                              mutProb)

答案 2 :(得分:0)

只要__init__()签名兼容,您就可以使用实例的类型而不是显式类型。

class Parent(object):
    def __str__(self):
        return 'I am a Parent'

    def reproduce(self):
        # do stuff common to all subclasses.
        print('parent reproduction')
        # then return an instance of the caller's type
        return type(self)()

class Child(Parent):
    def __str__(self):
        return 'I am a Child'

    def reproduce(self):
        # do stuff specific to Child.
        print('child reproduction')
        # call the parent's method but it will return a
        # Child object
        return super(Child, self).reproduce()


print(Parent().reproduce())

parent reproduction    
I am a Parent

print(Child().reproduce())

child reproduction
parent reproduction
I am a child