我有一个父类和两个子类 child1(parent) 和 child2(parent) 有点像下面的代码。(编辑以更正确地显示父类正在做某事)
class parent(object):
name = None
def __init__(self,e):
# process the common attributes
name = e.attrib['name']
def __new__(cls,e):
if e.attrib['type'] == 'c1':
return child1(e)
elif e.attrib['type'] == 'c2':
return child2(e)
else:
raise
class child1(parent):
extra1 = None
def __init__(self,e):
super(e)
# set attributes from e that are specific to type c1
class child2(parent):
extra2 = None
def __init__(self,e):
super(e)
# set attributes from e that are specific to type c2
Run Code Online (Sandbox Code Playgroud)
目标是能够根据参数的值获得“正确”的类。因此,如果我可以说obj = parent(element)并且obj将是child1或child2取决于价值element.attrib['type']是什么。
问题是,在内部parent.__new__,您正在调用child1(e),而同时调用child1.__new__,它会在 中找到实现parent.__new__并使用相同的e、 调用child1(e)、调用它......所以你会得到无限递归。
有更好的设计方法,但如果您只想修复您的设计,有以下三种选择:
如果您__new__在所有子类中定义,它就不会通过parent.__new__. 您可以通过intermediate在parent和之间插入一个类来一步完成此操作childN,因此您只需要intermediate.__new__. 或者使用他们都继承的 mixin,或者……
摆脱继承。是否有任何真正的原因child1是,一个parent在这里?
您似乎正在寻找在 Smalltalk/ObjC 术语中称为“类集群”的东西,并且您不需要集群的“可见面”作为 Python 中的基类,就像在这些语言中所做的那样。
例如:
class base(object):
pass
class parent(base):
def __new__(cls, e):
# same as before
class child1(base):
# etc.
Run Code Online (Sandbox Code Playgroud)
在 Python 中,你甚至可以制作parent一个 ABC,register每个都childN用它,这样你就可以使用isinstance它并与它成为朋友。
最后,您可以仅通过处理__new__onparent而不是其子类来捕获递归:
def __new__(cls, e):
if cls is not parent:
return super(parent, cls).__new__(cls)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2126 次 |
| 最近记录: |