问题描述
我在类 P1
中重载了加法运算符,使实例可以直接加在一起。但是,执行p1 + p2
时会发生内存错误。 p1.data + p2.data
可以给出正确的结果。
class P1:
def __init__(self):
self.data = np.zeros((512,512),dtype='float64')
def __setitem__(self,key,value):
self.data[key] = value
def __getitem__(self,item):
return self.data[item]
def __add__(self,other):
return self.data + other
def __radd__(self,other):
return other + self.data
p1 = P1()
p2 = P1()
p1 + p2
Traceback (most recent call last):
File "D:\professional\Anaconda_install\lib\site-packages\IPython\core\interactiveshell.py",line 3418,in run_code
exec(code_obj,self.user_global_ns,self.user_ns)
File "<ipython-input-224-a0c3d63f397c>",line 1,in <module>
p1 + p2
File "<ipython-input-221-ba43c19b29b0>",line 12,in __add__
return self.data + other
File "<ipython-input-221-ba43c19b29b0>",line 15,in __radd__
return other + self.data
MemoryError: Unable to allocate 2.00 MiB for an array with shape (512,512) and data type float64
谁能帮我解释一下?
解决方法
发生重载是因为您在创建 Feedback Loop 的 other
和 other.data
中使用了 __add__
而不是 __radd__
。
详细来说,您首先调用 p1.__add__(p2)
,这会导致解释器查找 p2.__radd__(p1)
,重复该过程,因为 p2.__radd__(p1)
查找 p1.__add__(p2)
。
也就是说,它永远无法返回,因为它会查找内容,在找到更多数据后保存值以完成计算,并在这个无休止的过程中耗尽可用内存。
解决方案:
import numpy as np
class P1:
def __init__(self):
self.data = np.zeros((512,512),dtype='float64')
def __setitem__(self,key,value):
self.data[key] = value
def __getitem__(self,item):
return self.data[item]
def __add__(self,other):
# return self.data + other.data
return np.array([*self.data,*other.data])
def __radd__(self,other):
# return other.data + self.data
return np.array([*other.data,*self.data])
虽然从技术上讲,您可以只交换 __add__
或 __radd__
之一,运算符重载仍然有效。