我正在为一个用 Python 编写的项目处理矩阵。我知道已经存在很多用于操作矩阵的库,但我正在编写自己的库,因此我确切地知道幕后发生了什么。
所以我有一个Matrix
基类和一个Vector
子类。两者都按预期单独工作,但如果使用单行或列初始化,我希望将 Matrix
变为 Vector
。
当使用正确的大小初始化Matrix
时,我尝试了类似self = Vector(...)
的方法。但这似乎并不影响该物体。我还想过调用 Vector
类的 __init__()
方法,但这还不够,因为我最重要的是 Vector
的方法。
有没有一种Python式的方法来处理这样的情况?
最佳答案
这是可以做到的,尽管这可能不是最好的方法。毕竟,如果实例化 Matrix
类,人们期望结果是一个 Matrix
实例。
实现此目的的一种方法是自定义 Matrix
类的构造函数:
class Matrix:
def __new__(cls, nrows, ncols):
if nrows == 1:
inst = super(Matrix, cls).__new__(Vector)
else:
inst = super(Matrix, cls).__new__(cls)
inst.nrows = nrows
inst.ncols = ncols
return inst
def __repr__(self):
return '{}(nrows={}, ncols={})'.format(
self.__class__.__name__, self.nrows, self.ncols)
演示:
>>> m1 = Matrix(2, 5)
Matrix(nrows=2, ncols=5)
>>> Matrix(1, 5)
Vector(nrows=1, ncols=5)
请注意,实例实际上是在 __new__()
方法内创建的,而 __init__()
用于初始化新创建的实例。
此外,正如 @Blckknght 下面的评论中提到的那样,通过 Matrix 类创建 Vector
实例可能会导致不必要的意外,例如 Vector
的 __init__()
方法未被调用(必须手动调用)。
不过,根据您的用例,最好保持干净并仅使用工厂来创建实例:
class Matrix:
def __init__(self, nrows, ncols):
self.nrows = nrows
self.ncols = ncols
def __repr__(self):
return '{}(nrows={}, ncols={})'.format(
self.__class__.__name__, self.nrows, self.ncols)
class Vector(Matrix):
pass
def make_matrix(nrows, ncols):
if nrows == 1:
return Vector(nrows, ncols)
return Matrix(nrows, ncols)
演示:
>>> make_matrix(1, 5)
Vector(nrows=1, ncols=5)
>>> make_matrix(2, 5)
Matrix(nrows=2, ncols=5)
当然,make_matrix()
也可以实现为Matrix
类的(类/静态)方法,但这将使父类与它的子类之一...
关于python - 根据父类初始化的条件初始化子类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47984126/