我有两个班级:
class Egg:
def __init__(self):
self._color = 'White'
class Larvae(Egg):
def __init__(self):
super().__init__()
self._color = 'Transparente'
说明......
所以,在我的代码中我有一个Egg实例。当我想将它们变成幼虫实例的时候。我可以创建一个Larvae实例并手工复制关于"之前"的信息。蛋实例。 Python为这样的东西提供了什么?对于"静音"其类的子类实例中的实例?
编辑:如下所述,此问题中的OOP并不是做出通缉行为的好方法。因此,在阅读答案时请记住这一点
答案 0 :(得分:3)
如何使用基于状态的方法?
class Ant:
def __init__(self, state='egg'):
self.state = state
@property
def color(self):
return {
'egg': 'Transparent',
'larvae': 'White,'
}[self.state]
def hatch(self):
if self.state == 'egg':
self.state = 'larvae'
else:
raise Exception('Cannot hatch if not an egg!')
答案 1 :(得分:1)
这是可能的,但不是一个好主意。
可以在构造对象后更改对象的类型,但是,它只是不健壮。更改对象的类型时,其__init__()
不会运行。旧类型遗留下来的任何属性仍然存在,如果它们与属于新类型的属性发生冲突,您可能会遇到令人讨厌的混乱。如果您确定这是正确的方法,则可以通过分配__class__
属性(例如spam.__class__ = SomeClass
)来实现。不过,我强烈建议不要这样做。
相反,我建议将要保留的数据分解为“状态”属性,然后将其从一种类型转移到另一种类型。例如:
class Egg(object):
def __init__(self, state):
# Other egg-related stuff here...
self.state = state
def grow_up(self):
return Larva(self.state)
class Larva(object):
def __init__(self, state):
# Other larva-related stuff here...
self.state = state
def grow_up(self):
return Pupa(self.state)
class Pupa(object):
# and so on...
spam = Egg([1, 2, 3])
spam = spam.grow_up()
print(spam.state) # [1, 2, 3]
答案 2 :(得分:1)
这个答案与你的要求没什么关系,但我发现你的OOP有点违反直觉是值得的。 OOP的重点是创建一个直观的继承层次结构。如果您的低级别课程应该知道更高级别的课程,那么在OO中没有什么意义。在您的用例中,Egg
必须知道Larvae
才能进行转换,但这没有多大意义。父类不应引用其子类。
class BaseInsect(object):
"""
Some stuff that all insects share at any stage
"""
def __init__(self, colour, *args, **kwargs):
self.colour = colour
...
class ImmatureAnt(BaseInsect):
...
class Egg(ImmatureAnt):
"""
Some egg-specific stuff
"""
def __init__(self, *args, **kwargs):
super(Egg, self).__init__("white")
...
class Larvae(ImmatureAnt):
def __init__(self, *args, **kwargs):
super(Larvae, self).__init__("transparent")
...
@staticmethod
def from_egg(egg, *args, **kwargs):
# make a larvae out of an egg
...
class BaseAdultAnt(BaseInsect):
"""
Some stuff all adult ants have
"""
...
class WorkerAnt(BaseAdultAnt):
...
class BaseReproducingAnt(BaseAdultAnt):
...
class Male(BaseReproducingAnt):
...
class Queen(BaseReproducingAnt):
...
回到你的问题。
您已经被告知可以将Egg
实例传递给Larvae
构造函数。这将是一个美丽的方式。为了使这个答案略微偏离主题,我提供了另一种解决方案。您可能想要使用多个函数。
def egg_to_larvae(egg, *args, **kwargs):
"""
:param egg: an Egg instance
:type egg: Egg
"""
# do some stuff to get all the info needed to create a larvae...
return larvae
def larvae_to_pupae(larvae, *args, **kwargs):
...
return pupae
你明白了
答案 3 :(得分:0)
只需使用公共基类,而不是尝试从Larvae
继承Egg
:
class AntBase:
def __init__(self, color):
self._color = color
class Egg(AntBase):
def __init__(self, color='White'):
super().__init__(color)
class Larvae(AntBase):
def __init__(self, color='Transparente'):
super().__init__(color)
虽然Egg
和Larvae
相似(都与蚂蚁相关),但Larvae
不是Egg
,也不是Egg
a {{1 }}。
他们都是" ant-things"但是,我们为你所有的蚂蚁事物创建了一个共同的Larvae
类。
要将AntBase
转换为Egg
,您可以拥有转换器Larvae
:
classmethod
现在你可以这样做:
class AntBase:
def __init__(self, color):
self._color = color
@classmethod
def transform_from(cls, instance):
return cls(instance._color)
您甚至可以为每个班级设置自定义行为:
egg0 = Egg()
larvae0 = Larvae.transform_from(egg0)