cython类使用Deepcopy函数的问题 [英] issue using deepcopy function for cython classes

查看:153
本文介绍了cython类使用Deepcopy函数的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近一直在与Cython一起玩,以提高速度,但是当我尝试使用copy.deepcopy()时发生了一些错误.这是代码:

I've been playing with Cython recently for the speed ups, but when I was trying to use copy.deepcopy() some error occurred.Here is the code:

from copy import deepcopy

cdef class cy_child:
    cdef public:
        int move[2]
        int Q
        int N
    def __init__(self, move):
        self.move = move
        self.Q = 0
        self.N = 0      

a = cy_child((1,2))

b = deepcopy(a)

这是错误:
can't pickle _cython_magic_001970156a2636e3189b2b84ebe80443.cy_child objects

This is the error:
can't pickle _cython_magic_001970156a2636e3189b2b84ebe80443.cy_child objects

如何解决此代码的问题?

How can I solve the problem for this code?

推荐答案

正如hpaulj在评论中所说,deepcopy看起来默认使用pickle来完成其工作. Cython cdef class es以前不是可腌制的. 在最新版本的Cython中,只要有可能,(另请参见 http://blog.behnel. de/posts/whats-new-in-cython-026.html ),但对数组进行腌制似乎是一个问题(即使没有数组我也无法正常工作).

As hpaulj says in the comments, deepcopy looks to use pickle by default to do its work. Cython cdef classes didn't used to be pickleable. In recent versions of Cython they are where possible (see also http://blog.behnel.de/posts/whats-new-in-cython-026.html) but pickling the array looks to be a problem (and even without the array I didn't get it to work).

解决方案是自己实现相关功能.我已经完成了 __deepcopy__ ,因为它很简单,但是您可以实施 pickle协议

The solution is to implement the relevant functions yourself. I've done __deepcopy__ since it's simple but alternatively you could implement the pickle protocol

def __deepcopy__(self,memo_dictionary):
    res = cy_child(self.move)
    res.Q = self.Q
    res.N = self.N
    return res

我怀疑随着Cython改进其pickle的实现,您将来不需要这样做.

I suspect that you won't need to do that in the future as Cython improves their pickle implementation.

关于memo_dictionary的注释:假设您有

a=[None]
b=[A]
a[0]=B
# i.e. A contains a link to B and B contains a link to A
c = deepcopy(a)

memo_dictionarydeepcopy用于记录已复制的内容,以使其不会永远循环.您不需要自己做很多事情.但是,如果您的cdef类包含一个Python对象(包括另一个cdef类),则应这样复制它:

memo_dictionary is used by deepcopy to keep a note of what it's already copied so that it doesn't loop forever. You don't need to do much with it yourself. However, if your cdef class contains a Python object (including another cdef class) you should copy it like this:

cdef class C:
    cdef object o
    def __deepcopy__(self,memo_dictionary):
        # ...
        res.o = deepcopy(self.o,memo_dictionary)
        # ...

(即确保将其传递给deepcopy的进一步调用)

(i.e. make sure it gets passed on to further calls of deepcopy)

这篇关于cython类使用Deepcopy函数的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆