我正在与矩阵合作,为我在python写的项目。我知道许多图书馆已经存在用于操纵矩阵,但我正在写自己的矩阵,所以我确切地知道引擎盖下发生了什么。
所以我有一个Matrix
基类和Vector
子类。两者都按预期工作,但如果用单行或列初始化,我希望Matrix
成为Vector
。
我尝试了self = Vector(...)
之类的东西,当时Matrix
的大小初始化。但这似乎不会影响对象。我还想到调用Vector
类的__init__()
方法,但这还不够,因为我最重要的是Vector
的方法。
是否有一种处理这种情况的Pythonic方法?
这可以做到,尽管这可能不是这样做的最佳方法。毕竟,如果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下面的评论中提到的那样,通过矩阵类创建Vector
实例可能会导致不必要的惊喜,例如Vector
的__init__()
方法未被调用(必须手动称呼它)。
不过,根据您的用例,因此可以保持清洁并使用 factory 例如创建可能会更好:
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
类的(类/静态)方法实现,但这将使父级与其子类之一相结合...