我正在实现一个类,它可以处理基本的二进制操作,例如加法,乘法,减法和除法,以及它们各自的变体(反转,就地)。我遇到了一个意想不到的行为,我试图理解。不幸的是,即使通过查看numpy的__add__
的unsignedinteger
实现,我也不能。
要重现此行为,只需运行以下代码:
import numpy as np
class test:
def __init__(self):
self.a = 1
def __len__(self):
return 1
def __getitem__(self, index):
print("getitem")
return self.a
def __radd__(self, other):
return self.a + other
a = test()
b = np.uint8(1) + a
这将导致__getitem__
循环。当然,我的实际代码的工作方式有点不同,但仍然面临着完全相同的问题。我还尝试使用python调试器,以便更好地理解实际调用的操作的行为。我想做的主要是,当我运行这段代码时:
b = np.uint8(10) + test()
实际执行__radd__
操作。我理解这是因为numpy.unsignedinteger.__add__
正在执行。有没有什么pythonic的方法来防止或者更好地修复它?
1条答案
按热度按时间6psbrbz91#
我理解这是因为
numpy.unsignedinteger.__add__
正在执行。有没有什么pythonic的方法来防止或者更好地修复它?给定表达式
np.uint8(10) + test()
,您的test
类无法阻止numpy的__add__
方法的调用。只有当numpy在其方法中返回
NotImplemented
时,才会调用__radd__
。你看到的无限
__getitem__
循环正在发生,因为你的类的行为就像一个无限序列,numpy想把它们的标量添加到这个无限序列的每个元素中。永远不会结束。你有两种方法来解决这个问题。第一种选择:让你的类成为一个适当的有限序列,让numpy处理操作。这不会调用您的
__radd__
方法。要使你的类成为一个有限序列,当索引大于0或小于-1(
-1
)时,你必须在__getitem__
中加入raise IndexError
。第二个选择:删除
__getitem__
方法。然后numpy意识到它不能将自己添加到你的类型中,返回NotImplemented
并让你的__radd__
方法处理操作。