英文:
__radd__ operation with numpy number results to __getitem__ loop
问题
I am implementing a class that handles basic binary operations such as addition, multiplication, subraction and division with their respective variants (reversed, in-place). I encountered an unexpected behaviour that I am trying to understand. Unfortunately, even by looking at numpy's implementation of __add__
of unsignedinteger
, I can not.
To reproduce this behavior you can simply run this code :
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
It will result in a __getitem__
loop.
Of course my actual code works a bit differently but still faces the exact same issue.
I also tried to use python debugger in order to better understand the behavior of the operation that actually was called.
What I wish to do is mainly, when I run this code :
b = np.uint8(10) + test()
To actually execute __radd__
operation. I understand it is happening because numpy.unsignedinteger.__add__
is executed. Is there any pythonic way to prevent or even better, to fix it?
英文:
I am implementing a class that handles basic binary operations such as addition, multiplication, subraction and division with their respective variants (reversed, in-place). I encountered an unexpected behaviour that I am trying to understand. Unfortunately, even by looking at numpy's implementation of __add__
of unsignedinteger
, I can not.
To reproduce this behavior you can simply run this code :
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
It will result in a __getitem__
loop.
Of course my actual code works a bit differently but still faces the exact same issue.
I also tried to use python debugger in order to better understand the behavior of the operation that actually was called.
What I wish to do is mainly, when I run this code :
b = np.uint8(10) + test()
To actually execute __radd__
operation. I understand it is happening because numpy.unsignedinteger.__add__
is execute. Is there any pythonic way to prevent or even better, to fix it ?
答案1
得分: 4
I understand it is happening because numpy.unsignedinteger.__add__
is executed. Is there any pythonic way to prevent or even better, to fix it?
给定表达式 np.uint8(10) + test()
,没有办法阻止您的 test
类调用numpy的 __add__
方法。
只有当numpy在其方法中返回 NotImplemented
时,才会调用您的 __radd__
。
您所看到的无限 __getitem__
循环发生,因为您的类表现得像一个无限序列,numpy想要将其标量添加到该无限序列的每个元素上。这永远不会结束。
您有两种修复方法。第一种选择:将您的类制作成一个合适的有限序列,让numpy处理该操作。这将不会调用您的 __radd__
方法。
要使您的类成为有限序列,必须在您的 __getitem__
中当索引大于零或小于负一(-1
)时 raise IndexError
。
第二种选择:去掉您的 __getitem__
方法。然后numpy会意识到它不能将自己添加到您的类型中,返回 NotImplemented
并让您的 __radd__
方法处理该操作。
英文:
> I understand it is happening because numpy.unsignedinteger.__add__
is execute. Is there any pythonic way to prevent or even better, to fix it ?
Given the expression np.uint8(10) + test()
there is no way your test
class can prevent the calling of numpy's __add__
method.
Only if numpy returned NotImplemented
in their method your __radd__
would be called.
The infinite __getitem__
loop you are seeing is happening, because your class behaves like an infinite sequence and numpy wants to add their scalar to every element of that infinite sequence. That will never finish.
You have two ways to fix this. First option: make your class a proper finite sequence and let numpy handle the operation. This will not call your __radd__
method.
To make your class a finite sequence you must raise IndexError
in your __getitem__
when the index is larger than zero or less than negative one (-1
).
The second option: get rid of your __getitem__
method. Then numpy realizes it cannot add itself to your type, return NotImplemented
and let your __radd__
method handle the operation.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论