我正在使用矩阵来处理我用Python编写的项目。我知道很多图书馆已经存在用于操纵矩阵但是我自己编写了这些库,所以我确切地知道幕后发生了什么。
所以我有一个Matrix
基类和一个Vector
子类。两者都按预期单独工作,但如果使用单行或列进行初始化,我希望Matrix
成为Vector
。
当self = Vector(...)
初始化为正确的大小时,我尝试了Matrix
之类的内容。但这似乎并没有影响到对象。我还想过调用__init__()
类的Vector
方法,但这还不够,因为我最重要的是Vector
方法。
是否有处理这种情况的pythonic方式?
答案 0 :(得分:2)
这可以做到,虽然它可能不是最好的方法。毕竟,如果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
的{{1}没有被调用的方法(必须手动调用)。
根据您的使用情况,最好保持清洁,只需使用 factory 进行实例创建:
__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()
类的(类/静态)方法实现,但这会使父类与其子类之一更紧密地耦合......