如何使类构造函数返回子类的对象?



我正在用Python编程。我有一个Base类,其中包含几个方法。有一些子类;他们可能有自己的方法。我希望Base类构造函数创建的对象不是类本身的对象,而是根据参数创建的一个子类的对象。

例如,假设我们的子类是PointLinePlane,它们都继承自Base,它们之间的区别由Base类的dim属性决定。

class Base():

def __init__(self, dim, a, b):
self.dim = dim
self.a = a
self.b = b

class Point(Base):

def __init__(self, a, b):
super().__init__(1, a, b)

class Line(Base):

def __init__(self, a, b):
super().__init__(2, a, b)

class Plane(Base):

def __init__(self, a, b):
super().__init__(3, a, b)

如果我显式地创建一个Point,对象类型将是Point:

pointA = Point(0, 0)
type(pointA) # __main__.Point

但是如果我通过Base构造函数做同样的事情,对象将属于Base类:

pointB = Base(1, 0, 0)
type(pointB) # __main__.Base

所以我想改变这种行为,使Base构造函数返回Point,LinePlane对象,如果dim属性分别等于1,2或3。我该怎么做呢?

编辑:基于这个线程(不正确地使用__new__来生成类实例?)我覆盖了Base.__new__(),得到了以下代码:

class Base():

def __new__(cls, a, b, dim):
if dim == 1:
return object.__new__(Point)
elif dim == 2:
return object.__new__(Line)
elif dim == 3:
return object.__new__(Plane)    

class Point(Base):

def __init__(self, a, b, dim):
self.a = a
self.b = b

class Line(Base):

def __init__(self, a, b, dim):
self.a = a
self.b = b

class Plane(Base):

def __init__(self, a, b, dim):
self.a = a
self.b = b

上面的代码可以工作,但是即使在创建新的Point实例时,它也需要显式设置dim参数。Base.__new__()Point.__init__()中不相同的一组参数会引发错误。我怎么能保持这种行为,但从Point构造器中删除dim?

您通常不希望通过实例化基准情况来完成此操作。虽然我认为你可以重写__new__,但我不建议这样做。值得注意的是,__init__有一个None返回类型。因此,无论如何,您不能在__init__中这样做-对象在那时已经创建了。

相反,你可能想要的是一个静态的所谓的"工厂"方法在你的基类:

from typing import Type
class Base():
@staticmethod
def create(dim, a, b) -> Type[Base]:
# Decide which subclass you want to create, instantiate and return it.
...
new_obj = Base.create(x, y, z)

最新更新