在 Python 中使用重载加法运算符时出现内存错误

问题描述

我在类 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 Loopotherother.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__ 之一,运算符重载仍然有效。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...