Mik*_*e R 5 python numpy magic-methods pandas
我定义了一个类,它的__ge__方法返回自身的一个实例,并且__bool__不允许调用其方法(类似于 Pandas Series)。
为什么X.__bool__在 during 中被调用np.int8(0) <= x,而不是在其他任何示例中被调用?谁在调用它?我已经阅读了数据模型文档,但我还没有在那里找到答案。
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
Run Code Online (Sandbox Code Playgroud)
X.__array_priority__ = 1000
最大的提示是它可以与pd.Series.
首先我尝试X继承自pd.Series. 这有效(即__bool__ 不再调用)。
为了确定 NumPy 是否使用isinstance检查或鸭子类型方法,我删除了显式继承并添加了(基于此答案):
@property
def __class__(self):
return pd.Series
Run Code Online (Sandbox Code Playgroud)
该操作不再起作用(即被__bool__调用)。
所以现在我认为我们可以得出结论 NumPy 正在使用鸭子类型方法。因此我检查了哪些属性正在被访问X。
我添加了以下内容X:
def __getattribute__(self, item):
print("getattr", item)
return object.__getattribute__(self, item)
Run Code Online (Sandbox Code Playgroud)
再次实例化为X并x调用np.int8(0) <= x,我们得到:
getattr __array_priority__
getattr __array_priority__
getattr __array_priority__
getattr __array_struct__
getattr __array_interface__
getattr __array__
getattr __array_prepare__
<__main__.X object at 0x000002022AB5DBE0>.__ge__
<__main__.X object at 0x000002021A73BE50>.__bool__
getattr __array_struct__
getattr __array_interface__
getattr __array__
Traceback (most recent call last):
File "<stdin>", line 32, in <module>
np.int8(0) <= x
File "<stdin>", line 21, in __bool__
assert False
AssertionError
Run Code Online (Sandbox Code Playgroud)
啊哈!什么是__array_priority__?谁在乎呢,真的。经过一点挖掘,我们需要知道的是NDFrame(从中pd.Series继承)将此值设置为1000。
如果我们添加X.__array_priority__ = 1000,它就会起作用!__bool__不再被称为。
是什么让这变得如此困难(我相信)是 NumPy 代码没有出现在调用堆栈中,因为它是用 C 编写的。如果我尝试了此处的建议,我可以进一步调查。
| 归档时间: |
|
| 查看次数: |
68 次 |
| 最近记录: |