我定义了一个类,其中它的 __ge__
方法返回自身的一个实例,其 __bool__
不允许调用方法(类似于 Pandas Series
)。
为什么是 X.__bool__
在 np.int8(0) <= x
期间调用,但不适用于任何其他示例? 谁在调用它?我已阅读 Data Model docs,但我还没有在那里找到我的答案。
import numpy as np
import pandas as pd
class X:
def __bool__(self):
print(f"{self}.__bool__")
assert False
def __ge__(self, other):
print(f"{self}.__ge__")
return X()
x = X()
np.int8(0) <= x
# Console output:
# <__main__.X object at 0x000001BAC70D5C70>.__ge__
# <__main__.X object at 0x000001BAC70D5D90>.__bool__
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# File "<stdin>", line 4, in __bool__
# AssertionError
0 <= x
# Console output:
# <__main__.X object at 0x000001BAC70D5C70>.__ge__
# <__main__.X object at 0x000001BAC70D5DF0>
x >= np.int8(0)
# Console output:
# <__main__.X object at 0x000001BAC70D5C70>.__ge__
# <__main__.X object at 0x000001BAC70D5D30>
pd_ge = pd.Series.__ge__
def ge_wrapper(self, other):
print("pd.Series.__ge__")
return pd_ge(self, other)
pd.Series.__ge__ = ge_wrapper
pd_bool = pd.Series.__bool__
def bool_wrapper(self):
print("pd.Series.__bool__")
return pd_bool(self)
pd.Series.__bool__ = bool_wrapper
np.int8(0) <= pd.Series([1,2,3])
# Console output:
# pd.Series.__ge__
# 0 True
# 1 True
# 2 True
# dtype: bool
最佳答案
我怀疑 np.int8.__le__
被定义为而不是返回 NotImplemented
并出租 X.__ge__
接管,而是尝试返回类似 not (np.int(8) > x)
的内容,然后 np.int8.__gt__
引发 NotImplemented
.曾经X.__gt__(x, np.int8(0))
返回 X
的实例而不是 bool 值,那么我们需要调用 x.__bool__()
为了计算 not x
的值.
(仍在尝试追踪 int8.__gt__
的定义位置以确认。)
(更新:不完全。 int8
使用单个通用的丰富比较函数,该函数只是将值转换为 0 维数组,然后返回 PyObject_RichCompare
对数组和 x
的结果。)
我确实找到了 this function似乎最终实现了 np.int8.__le__
:
static NPY_INLINE int
rational_le(rational x, rational y) {
return !rational_lt(y,x);
}
如果参数之一(如 X
)不是 NumPy 类型,我不清楚我们如何避免使用此函数。我想我放弃了。
关于python - 与 NumPy 实例调用的相等性比较 `__bool__`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67929704/