【发布时间】:2017-03-08 06:11:49
【问题描述】:
在 Python 中,您的类的 __rmul__ 方法是否可以覆盖另一个类的 __mul__ 方法,而不更改其他类?
出现这个问题是因为我正在为某种类型的线性运算符编写一个类,并且我希望它能够使用乘法语法将 numpy 数组相乘。这是一个说明问题的最小示例:
import numpy as np
class AbstractMatrix(object):
def __init__(self):
self.data = np.array([[1, 2],[3, 4]])
def __mul__(self, other):
return np.dot(self.data, other)
def __rmul__(self, other):
return np.dot(other, self.data)
左乘可以正常工作:
In[11]: A = AbstractMatrix()
In[12]: B = np.array([[4, 5],[6, 7]])
In[13]: A*B
Out[13]:
array([[16, 19],
[36, 43]])
但右乘法默认为np.ndarray 的版本,它将数组拆分并逐个元素执行乘法(这不是我们想要的):
In[14]: B*A
Out[14]:
array([[array([[ 4, 8],
[12, 16]]),
array([[ 5, 10],
[15, 20]])],
[array([[ 6, 12],
[18, 24]]),
array([[ 7, 14],
[21, 28]])]], dtype=object)
在这种情况下,如何让它在原始(未拆分)数组上调用我自己类的__rmul__?
欢迎回答解决 numpy 数组的具体情况,但我也对覆盖另一个无法修改的第三方类的方法的一般想法感兴趣。
【问题讨论】:
-
为什么不使用
@运算符? -
我相信在通常的 XXX 方法之前检查 rXXX 方法的唯一情况是右侧对象是左侧物体。我对 numpy 内部结构了解得不够多,不知道它们是否可以被子类化。
-
From the docs -
These functions are only called if the left operand does not support the corresponding operation and the operands are of different types -
@FranciscoCouzo 作为从事数值分析的人,@ 运算符看起来很棒! python社区做出了多么棒的决定。我正在使用 Python 2.7.6,但仅此一项可能会让我转到 3.x。