如何在Python中从子类调用和重写父类方法
在如何在Python中从子类调用和重写父类方法,python,python-2.7,oop,inheritance,parent-child,Python,Python 2.7,Oop,Inheritance,Parent Child,在ResistantVirus类的Replicate方法中,我试图调用SimpleVirus类的Replicate(self,popDensity),但不是返回SimpleVirus对象,而是希望它返回ResistantVirus对象 显然,我也可以从SimpleVirus.Replicate方法中重复一些代码,并在我的ResistantVirus.Replicate方法中使用相同的实现,但我想知道是否可以调用并覆盖SimpleVirus.Replicate以避免重复 class SimpleV
ResistantVirus
类的Replicate
方法中,我试图调用SimpleVirus
类的Replicate(self,popDensity)
,但不是返回SimpleVirus
对象,而是希望它返回ResistantVirus
对象
显然,我也可以从SimpleVirus.Replicate
方法中重复一些代码,并在我的ResistantVirus.Replicate
方法中使用相同的实现,但我想知道是否可以调用并覆盖SimpleVirus.Replicate
以避免重复
class SimpleVirus(object):
def __init__(self, maxBirthProb, clearProb):
self.maxBirthProb = maxBirthProb
self.clearProb = clearProb
def reproduce(self, popDensity):
if random.random() > self.maxBirthProb * (1 - popDensity):
raise NoChildException('In reproduce()')
return SimpleVirus(self.getMaxBirthProb(), self.getClearProb())
class ResistantVirus(SimpleVirus):
def __init__(self, maxBirthProb, clearProb, resistances, mutProb):
SimpleVirus.__init__(self, maxBirthProb, clearProb)
self.resistances = resistances
self.mutProb = mutProb
def reproduce(self, popDensity)
## returns a new instance of the ResistantVirus class representing the
## offspring of this virus particle. The child should have the same
## maxBirthProb and clearProb values as this virus.
## what I sketched out so far and probs has some mistakes:
for drug in activeDrugs:
if not self.isResistantTo(drug):
raise NoChildException
break
simple_virus = SimpleVirus.reproduce(self,popDensity)
return ResistantVirus(simple_virus.getMaxBirthProb(),simple_virus.getClearProb())
用于调用父类的方法:
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)
用于调用父类的方法:
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)
看来我能帮你
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
copy方法将携带self
是什么的类(不一定是父类)。例如:
Child(1,2).copy() # <__main__.Child object at 0x01832E90>
以下内容有时会复制,有时会引发异常
res_virus = ResistantVirus(0.8, 0.2, ['a', 'b', 'c'], 0.1)
res_virus.reproduce(pop_density=0.3, drug_list=['a', 'b'])
请注意,这两个类之间没有明显的代码重用。如果你有一个严格的继承链,并且事情在你前进的过程中趋于“积累”,这是很好的。但是,如果您将有许多类都继承了SimpleVirus,并且其中一些类共享功能,那么它可能值得一看。它看起来可以帮助您
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
copy方法将携带self
是什么的类(不一定是父类)。例如:
Child(1,2).copy() # <__main__.Child object at 0x01832E90>
以下内容有时会复制,有时会引发异常
res_virus = ResistantVirus(0.8, 0.2, ['a', 'b', 'c'], 0.1)
res_virus.reproduce(pop_density=0.3, drug_list=['a', 'b'])
请注意,这两个类之间没有明显的代码重用。如果你有一个严格的继承链,并且事情在你前进的过程中趋于“积累”,这是很好的。但是,如果您将有许多类都继承
SimpleVirus
,并且其中一些类共享功能,那么可能值得一看。您可以使用实例的类型,而不是显式类型,只要\uu init\uuu()
签名兼容即可
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
只要签名兼容,就可以使用实例的类型而不是显式类型
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
您不应该在
\uuuu init\uuuu
方法中使用super()
除了类名称之外,不要使用CamelCase。还有getMaxBirthProb和getClearProb方法在哪里?抱歉,为了节省空间,我没有复制粘贴包含所有getter和setter方法的其余代码。还有其他的方法和事情需要做,所以我不想做和我在SimpleVirus.Replicate中所做的完全相同的事情。另外,我看到人们在代码中使用super(),我认为这只是调用父类方法时的另一种选择。我一直在init和其他编码项目中使用Classname.method(),效果很好。如果不使用super()并且只允许使用super(),这是一种不好的做法吗?不,有时候,super很有帮助,在多重继承的情况下,mixin。。。但有时,通过父类名称调用父类方法是实现绕过Python的MRO(方法解析顺序)实现的唯一方法。您不应该在\uuuu init\uuu
方法中使用super()。还有getMaxBirthProb和getClearProb方法在哪里?抱歉,为了节省空间,我没有复制粘贴包含所有getter和setter方法的其余代码。还有其他的方法和事情需要做,所以我不想做和我在SimpleVirus.Replicate中所做的完全相同的事情。另外,我看到人们在代码中使用super(),我认为这只是调用父类方法时的另一种选择。我一直在init和其他编码项目中使用Classname.method(),效果很好。如果不使用super()并且只允许使用super(),这是一种不好的做法吗?不,有时候,super很有帮助,在多重继承的情况下,mixin。。。但有时,通过父类名称调用父类方法是实现绕过Python的MRO(方法解析顺序)实现的唯一方法!我可能听起来很愚蠢,但请容忍我:有没有一种方法可以调用父类方法,但返回具有更多属性的子类方法?我注意到您使用了“return Child(self.a,self.b)”,如果我还想实现Parent.method()和其他Child.method(),该怎么办?我是否可以将返回的父对象放入变量中,并用子类对象初始化将其包装?再次抱歉,我的问题太长了。@BoiseDakota所以,您可能需要类似于返回Child.copy\u from\u parent(self.b)
的语法,其中self.a
的处理是由父级实现的copy
?否。我想知道在不实现新方法copy()的情况下。是否可以1.调用父方法2。添加更多特定于子类的实现。2.是否将父对象返回到子对象?非常感谢。“我现在很困惑,请容忍我。”博伊塞达科塔大概是吧?现在还不清楚你想做什么。如果你能想出一个你想要的结构的最小的例子,这将有助于澄清问题。谢谢你的回答!我可能听起来很愚蠢,但请容忍我:有没有一种方法可以调用父类方法,但返回具有更多属性的子类方法?我注意到您使用了“return Child(self.a,self.b)”,如果我还想实现Parent.method()和其他Child.method(),该怎么办?我是否可以将返回的父对象放入变量中,并用子类对象初始化将其包装?再次抱歉,我的问题太长了。@BoiseDakota所以,您可能需要类似于返回Child.copy\u from\u parent(self.b)
的语法,其中self.a
的处理是由父级实现的copy
?否。我想知道在不实现新方法copy()的情况下。是阿宝吗