Python:实例类变异

时间:2015-08-13 20:21:37

标签: python

我有两个班级:

class Egg:
    def __init__(self):
        self._color = 'White'

class Larvae(Egg):
    def __init__(self):
        super().__init__()
        self._color = 'Transparente'

说明......

Ant cycle illustration

所以,在我的代码中我有一个Egg实例。当我想将它们变成幼虫实例的时候。我可以创建一个Larvae实例并手工复制关于"之前"的信息。蛋实例。 Python为这样的东西提供了什么?对于"静音"其类的子类实例中的实例?

编辑:如下所述,此问题中的OOP并不是做出通缉行为的好方法。因此,在阅读答案时请记住这一点

4 个答案:

答案 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)

虽然EggLarvae相似(都与蚂蚁相关),但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)