python - 如何创建两个子类之一的新对象?
问题描述
我有动物课和两个儿童课鱼和熊
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 类型对象数组
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 中是否有一种简单的方法可以做到这一点,还是我需要创建自己的方法?
解决方案
从语义 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))
您可能还想检查abc 模块,了解一些更进化的功能 wrt/子类等。
推荐阅读
- reactjs - 为什么 fetchIntercept.register 在 redux-saga 模式中单击按钮时仅命中一次?
- sql - 插入或更新触发器后的 Oracle 12c
- python - 简单的 Flask 项目运行缓慢
- bash - 比较字符串是否包含在 bash
- excel - 使用固定的间接单元格引用动态获取工作表名称
- julia - 使用 Julia Mmap 复制一个大文件
- https - 在 SICStus Prolog 中使用带有库(枕头)的 https
- python - 数据流未显示流管道的输出收集计数?
- javascript - 原型方法可以做什么 es6 类不能?
- android - 用户可以从 google play store 下载以前版本的应用程序,即使在最新版本可用后也是如此。