python - 为什么 Python 没有 "__req__"(反射(reflect)相等)方法?

标签 python numpy python-internals python-datamodel

我有一个小助手类:

class AnyOf(object):
    def __init__(self, *args):
        self.elements = args
    def __eq__(self, other):
        return other in self.elements

这让我可以像这样施展甜蜜魔法:

>>> arr = np.array([1,2,3,4,5])
>>> arr == AnyOf(2,3)
np.array([False, True, True, False, False])

无需使用列表理解(如 np.array(x in (2,3) for x in arr)。

(我维护了一个 UI,允许(受信任的)用户输入任意代码,并且 a == AnyOf(1,2,3) 比列表理解更容易接受-精通技术的用户。)

但是!

这只有一种方法!例如,如果我要执行 AnyOf(2,3) == arr 那么我的 AnyOf 类的 __eq__ 方法永远不会被调用:相反, NumPy 数组的 __eq__ 方法被调用,它在内部(我假设)调用其所有元素的 __eq__ 方法。

这让我想知道:为什么 Python 不允许右侧等价于 __eq__? (大致等同于 __radd____rmul__ 等方法。)

最佳答案

在语言中,__req__ 可能被认为比有用 更令人困惑。考虑如果类 Left 定义了 __eq__ 而类 Right 定义了 __req__,那么 Python 有义务做一个 Left() == Right() 中谁先被调用的决定是一致的(我们可能希望结果是等价的,无论哪种方式)。他们不可能都赢。

但是,Python 数据模型确实允许您在这里做您想做的事情。您可以从任何一方控制此比较,但您需要以特定方式定义 AnyOf如果您希望AnyOf 从右侧控制eq,您可以将其定义为np.ndarray 的子类.

if I were to do AnyOf(2,3) == arr then my AnyOf class's __eq__ method never gets called

实际上,不,这里存在明显的根本误解。左侧总是首先尝试进行相等比较,除非右侧是左侧类型的子类。

arr == AnyOf(2,3)

在上面显示的比较中,您的自定义 __eq__ 正在 被调用,因为 numpy 数组调用它!所以 np.ndarray 获胜,它决定对每个元素检查一次。它实际上可以做任何其他事情,包括根本不调用您的 AnyOf.__eq__

AnyOf(2,3) == arr

在上面显示的比较中,您的类确实在比较中进行了第一次尝试,但由于使用了 in 的方式而失败了 - return other in self.elements 正在检查数组是否在元组中。

关于python - 为什么 Python 没有 "__req__"(反射(reflect)相等)方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47577395/

相关文章:

python - 为什么在 Django 中使用线程局部变量不好?

python - 在 Windows 到 Linux/OSX 中用 Python 交叉编译

python - str(list) 如何工作?

python - print 语句如何创建局部变量

python - 无法在 Conda 环境中安装 Gensim - 找不到 noarch 目录

python - 带 ndarray 的 ctypedef 引发 "Buffer types only allowed as function local variables"

Python Numpy 无法将 CSV 文件中的字符串转换为整数

python - 使用 NumPy 和 matplotlib 绘制的图形上未显示某些点

python - 为什么在同一行中创建的两个对象具有相同的对象,但这与列表不同?

Python freezeset 散列算法/实现