【问题标题】:How to create new object of one of two child class?如何创建两个子类之一的新对象?
【发布时间】:2023-03-19 23:50:01
【问题描述】:

我有Animal类和两个ChildFishBear

class Fish(Animal):

    def __init__(self, x, y, parent_engine):
        self.parent = parent_engine
        self.x = x
        self.y = y
        self.type = 2
        self.image = '????'
        self.life = 1


class Bear(Animal):

    def __init__(self, x, y, parent_engine):
        self.parent = parent_engine
        self.x = x
        self.y = y
        self.type = 3
        self.image = '????'
        self.life = 1

在代码中,我有一个名为 Field

Animal type 对象数组
class Engine:

    def __init__(self, size):
        self.field = []
        self.field_size = size

我有函数 create_actor_child 和输入 actor (Animal object)。这个函数应该用相同的子类创建新的Animal。我正在使用 if - watch is Parent Bear - 生成熊,否则生成鱼。但是,如果我要生 10 个孩子,那就很难了。我认为应该有解决方案来创建父类的新副本。

def create_actors_child(self, actors):  # returns parents back

    sample = actors[0]

    x = sample.x
    y = sample.y

    for actor in actors:
        actor.go_back_event()

    if sample.type == 2:
        self.field.append(bp.Fish(x, y, self))
    else:
        self.field.append(bp.Bear(x, y, self))

我需要像self.field.append(parent_class(actor)) 这样的东西。

在 Python 中是否有一种简单的方法可以做到这一点,还是我需要创建自己的方法?

【问题讨论】:

    标签: python arrays class parent-child


    【解决方案1】:

    从语义 POV 来看,继承描述了“是”关系,因此(只要您的子类尊重 liskov 的替换原则)鱼或熊已经是动物。此外,创建“父类的新副本”实际上会创建新的不同对象,这肯定不是您想要的。

    更好的解决方案是保留子类的注册(dict)(使用type作为键)并提供工厂函数或方法,即:

    class Animal(object):
        # your code here
    
    
        # XXX : Q&D code, missing sanity checks and error handling
        __registry = {}
    
        @classmethod
        def register(cls, subcls): 
            cls.__registry[subcls.type] = subcls
    
        @classmethod
        def create(cls, type, x, y, engine):
            return cls.__registry[type](x, y, engine)
    
    
    
    class Engine(object):
    
        def create_actors_child(self, actors):  # returns parents back
    
            sample = actors[0]
    
            x = sample.x
            y = sample.y
    
            for actor in actors:
                actor.go_back_event()
    
            self.field.append(Animal.create(sample.type, x, y, self))
    

    请注意,此时如果Animal.type 没有任何其他用途,您也可以直接使用子类本身(并摆脱注册表):

        def create_actors_child(self, actors):  # returns parents back
    
            sample = actors[0]
    
            x = sample.x
            y = sample.y
    
            for actor in actors:
                actor.go_back_event()
    
            samplecls = type(sample)
            self.field.append(samplecls(x, y, self))
    

    您可能还想查看the abc module 以了解更多改进的功能 wrt/ 子类等。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-19
      • 1970-01-01
      • 1970-01-01
      • 2020-06-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多