Python 中二元函数的正确模式

Proper pattern for dyadic functions in Python

我有一个 Python 程序,它有一个问题,我的头因范围规则而旋转。

假设我们有一个名为 Matrix 的 class。在内部,它包含二维数字射线。所以实例化它的核心看起来像:

z = Matrix([values])

所以实例 z 获取列表的列表并创建一个实例,其中 z.internal_matrix 是一个属性,其中包含传入的类似矩阵的列表。

我总是被困住的问题是:如果你正在构建像 "matrix_mult"?

这样的二元函数,你如何构建代码以使其具有最大的可靠性和清晰度

注意当你要调用的函数是一个变量的函数时,这个问题较少出现。如果是这样,在代码中我们可以有一个像 "determinant" 这样的函数,它是 monadic 并且引用 self。所以,我认为我们更喜欢

z.determinant()

行列式是在class内部声明的函数(与init相同)。

现在假设我们有一个像乘法这样的二元函数,叫做 'matrix_multiply'。我们可以将其定义在与 init 相同的级别。

现在语法变得有点谨慎 - 表明 'calling instance' 在某种意义上对其数据更有特权 - 因为我们可能会这样做

z = self.matrix_multiply(y)

其中 y 是同一 class 的另一个对象。我们也可以做得同样好:

z = y.matrix_multiply((x))

最后,可以在 maxtrix_multiply 的某个级别创建函数。它将了解所有 class 内部结构、数据和方法。然后我们可以写:

z = matrix_multiply(x, y)

其中 matrix_multiply 可以是 class 的成员(方法),或者它可以像 FORTRAN 子程序一样独立;它只需要知道如何通过 "reaching into" 对象框和访问内部例程来实例化一个新变量。这样做可以清楚地表明它不是 class 或 class 实例内部的 "magic" 函数。

但是,要工作,matrix_multiply 必须对 class/instance 变量有透彻的了解,这样它才能对任何实例施展魔法 "outside"。

试图考虑所有的可能性 - 并让其中一个发挥作用 - 正在耗尽我的大脑。在这种情况下一般的建议是什么?

我可能会在 Matrix class 上选择一个名为 multiplyclassmethod。它会被称为 z = Matrix.multiply(x, y)。这样就避免了任何关于其中一个操作数是 "more privileged" 的建议,并将与 Matrix class 内部相关的所有逻辑保留在 Matrix class 中.

class Matrix:
    def __init__(self, values):
        ...

    @classmethod
    def multiply(cls, left: 'Matrix', right: 'Matrix') -> 'Matrix':
        ...
        return result

然而,这是在不知道您的 project/application. 的任何其他上下文的情况下,例如,如果代码看起来可能在您的应用程序中更有意义喜欢

z = x.multiply(y)

在这种情况下,您应该将其作为 Matrix class.

上的常规方法来实现

最后,如果你想能够写

z = x * y

那么你需要在Matrix上实现__mul__方法 class:

class Matrix:
    ...
    def __mul__(self, other: 'Matrix') -> 'Matrix':
        ...
        return result