python - 根据父类初始化的条件初始化子类

标签 python matrix subclass

我正在为一个用 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/

相关文章:

r - 将数据框转换为邻接矩阵/边列表以进行网络分析

java - 比较具有相同父类(super class)的 2 个子类实例

Java:监听器子类不会更改父类(super class)按钮

python - 如何在 Windows 中使用子进程

c++ - 矩阵如何自相乘?

python - 带有 python -c "python code here"命令返回参数的 cURL 命令

无法在字符数组中 scanf '-' 或 '+'

xcode - 使用 Storyboard或以编程方式创建 View 时自定义初始化

python - 将 HTML 列表 (<li>) 转换为制表符(即缩进)

python - Django - 通过验证过滤范围内的日期