我正在用Python编程。我有一个Base
类,其中包含几个方法。有一些子类;他们可能有自己的方法。我希望Base
类构造函数创建的对象不是类本身的对象,而是根据参数创建的一个子类的对象。
例如,假设我们的子类是Point
、Line
和Plane
,它们都继承自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
,Line
或Plane
对象,如果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)