Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 从int继承的Cython扩展类型导致MemoryError_Python_Inheritance_Crash_Cython - Fatal编程技术网

Python 从int继承的Cython扩展类型导致MemoryError

Python 从int继承的Cython扩展类型导致MemoryError,python,inheritance,crash,cython,Python,Inheritance,Crash,Cython,我正在尝试创建一个从int或cython.int继承的扩展类型。这对我来说是必要的,因为我需要能够使用这种类型作为一些列表/数组的索引 下面是用Anaconda上的Cython v0.22在Python 2.7.9 Win32(我运行的是Windows 7)上重现错误的代码: import cython cimport cython import sys cdef class ExtendedInt(int): #cdef object __weakref__ # expli

我正在尝试创建一个从int或cython.int继承的扩展类型。这对我来说是必要的,因为我需要能够使用这种类型作为一些列表/数组的索引

下面是用Anaconda上的Cython v0.22在Python 2.7.9 Win32(我运行的是Windows 7)上重现错误的代码:

import cython
cimport cython


import sys


cdef class ExtendedInt(int):


    #cdef object __weakref__ # explicitly enable weakref for this extension type, will self-destruct when it is no longer strongly referenced.


    def __add__(a, b):
        return a+b


# Simple test case
def main():
    total_it = 1000
    for i in xrange(total_it):
        for j in xrange(10000000):
            ExtendedInt(j)
        sys.stdout.write("\rGenerating lists of ExtendedInt : %i/%i" % (i, total_it))
发生的情况是,如果您尝试创建大量ExtendedInt,Python解释器将在某个时刻因MemoryError崩溃。对于上面的代码片段,在我的内存为4GB的机器上,它在第11次迭代时崩溃,但这取决于机器规格。我试图启用weakref,但它无法解决问题

但是,如果您将“cdef class ExtendedInt(int):”替换为“class ExtendedInt(int)”(因此它不再是一个扩展类型,而是一个简单的Python类),那么问题就不会发生,也不会出现内存错误崩溃

因此,即使启用了weakref,从整数继承的扩展类型似乎也没有被正确释放。这是我应该在追踪器上填写的错误还是我遗漏了什么

这是当前Cython版本的bug吗?我在bugtracker上找不到任何参考资料。。。或者我错过了一些可以解决问题的方法?

:

您的扩展类型自动继承“int_free”插槽 函数的基类型,因此“int_dealloc()中的“else”情况 实际上,将调用“int_free()”并将该对象附加到空闲列表中 尽管不完全是PyInt类型。然后,在创建新的 ExtendedInt实例,Python的int子类型实例化代码 忽略自由列表,而是创建一个全新的对象

因此,空闲列表一直在增长,直到它填满所有内存和内存 过程死亡。我创建了一张CPython票

这是我的建议

以下是Guido Van Rossum的答案:

预期的解决方案是要求int子类重写 免费

请注意,这段代码大部分是在假设 子类是使用class语句(在常规Python中)创建的 模块,而不是Cython),负责所有这些细节。那不是 我的意思是Cython尝试这个是错误的,但它确实意味着没有太多 这也意味着我不认为你 报告的符合CPython中的错误条件


所以我不确定这是否会得到修复,或者Cython是否会实施一种变通方法。无论如何,对于那些面临与我相同问题的人,您可以通过从object继承来解决这个问题,然后只需重新实现整数的神奇方法,如intindexadd,等等,正如我所解释的。

您是否尝试过
cdef类ExtendedInt(cython.int):
?您提到了它,但在您的示例中,您似乎得到了Python
int
…是的,我试过了,但效果并不好。无论如何,我确认这是当前Cython邮件列表中的一个bug。