问题描述
我最近一直在与Cython一起玩,以提高速度,但是我的项目继承了一个模块,该模块具有 copy()
方法,该方法使用 deepcopy()
。我试着在 copy()
的重写版本中实现 deepcopy()
,我以为可以正常工作了,
I've been playing with Cython recently for the speed ups, but my project inherits a module that has a copy()
method which uses deepcopy()
. I tried implementing the deepcopy()
within an overrided version of copy()
, and I thought I had it working, but it doesn't appear to be anymore.
TypeError: object.__new__(cython_binding_builtin_function_or_method) is not safe,
use cython_binding_builtin_function_or_method.__new__()
这是在python / lib / copy_reg.py中发生的:
This is occuring in python/lib/copy_reg.py here:
return cls.__new__(cls, *args)
我在这里使用Python 2.7。较新版本的Python是否有可能以安全的方式从 deepcopy()
返回?我也在使用最新版本的Cython,版本为0.15.1。
I'm on Python 2.7 here. Is it possible that a newer version of Python returns from deepcopy()
in a "safe" way? I'm also on the latest version of Cython, 0.15.1.
注意我已经删除了以前的更新,以使其尽可能简单。
好!我想我发现了这种不兼容,但我真的不知道该怎么办。
Ok! I think I found the incompatibility but I don't really know what to do about it.
class CythonClass:
def __init__(self):
self._handle = self._handles.get("handle_method")
def call_handle(self):
self._handle(self)
def handle_method(self):
print "I'm a little handle!"
handles = {"handle_method", handle_method}
然后在我的主目录中应用程序:
Then in my main app:
from cython1 import CythonClass
from copy import deepcopy
if __name__ == "__main__":
gc1 = CythonClass()
gc1.call_handle()
gc2 = deepcopy(gc1)
我得到:
I'm a little handle!
Traceback (most recent call last):
File "cythontest.py", line 8, in <module>
gc2 = deepcopy(gc1)
File "C:\python26\lib\copy.py", line 162, in deepcopy
y = copier(x, memo)
File "C:\python26\lib\copy.py", line 292, in _deepcopy_inst
state = deepcopy(state, memo)
File "C:\python26\lib\copy.py", line 162, in deepcopy
y = copier(x, memo)
File "C:\python26\lib\copy.py", line 255, in _deepcopy_dict
y[deepcopy(key, memo)] = deepcopy(value, memo)
File "C:\python26\lib\copy.py", line 189, in deepcopy
y = _reconstruct(x, rv, 1, memo)
File "C:\python26\lib\copy.py", line 323, in _reconstruct
y = callable(*args)
File "C:\python26\lib\copy_reg.py", line 93, in __newobj__
return cls.__new__(cls, *args)
TypeError: object.__new__(cython_binding_builtin_function_or_method) is not safe, use cython_binding_builtin_function_or_method.__new__()
键是函数/句柄引用:
handles = {"handle_method", handle_method}
如果我不这样做,包括方法/功能参考,Cython在深度复制期间不会爆炸。如果我添加一个,那不喜欢deepcopy / copy_reg如何复制引用。
If I don't include the method/function reference, Cython will not blow up during deepcopy. If I include one, it doesn't like how deepcopy/copy_reg copies the reference over.
除了不使用方法/函数引用之外,还有其他想法吗?如果有一个简单的答案,我有一些麻烦。 (当我完成此输入时,我已经在使用它了)
Any ideas besides not using method/function references? I have a bit of untangling to do if that the simple answer. (which I'm already working on as I finish typing this)
谢谢!
推荐答案
啊,终于找到了回答您自己的问题按钮。
Ah, finally found the "Answer your own question" button.
我可能不耐烦,但是由于没有人回复(我的意思是(谁正在使用Cython并在星期四的下午回答问题),我想我应该关闭它。
I'm probably being impatient, but since nobody has replied yet (I mean who's using Cython and answering questions on a Thursday afternoon), I thought I would close this one off.
1)Cython不喜欢对具有功能/方法引用的变量。这些可变副本将失败。据我所知,没有解决方法,您只需要提出不需要它们的新设计即可。我最终在上面和我的项目中使用了相同的代码。
1) Cython doesn't like deepcopy on Classes which have function/method referenced variables. Those variable copies will fail. From what I can tell, there's no working around it, you just have to come up with an new design that doesn't require them. I ended up doing so with the same code above, and in my project.
2)Cython根本不处理属性装饰器。您不能 @属性
和 @ 。需要以旧的方式设置属性。例如
<属性名称> = property(get_property,set_property)
。
2) Cython doesn't handle the property decorators at all. You can't @property
and @<property name>.setter
. Properties need to be set the old fashion way. e.g. <property name> = property(get_property, set_property)
.
3)无法访问继承的非Cython类的方法可能。我知道这个含糊。我无法完全解释。我要说的是我继承了 NetworkX.DiGraph
,而在Cython之后,当我无法访问 number_of_nodes()
时,它是直接的Python。我必须创建该方法的引用并使用它。例如 number_of_verts = NetworkX.DiGraph.number_of_nodes
。
3) An inherited non-Cython class's methods "might" not be accessible. I know this vague. I can't completely explain it. All I'll say is I was inheriting NetworkX.DiGraph
, and number_of_nodes()
was no accessible after Cython, when it was straight Python. I had to create a reference to the method and use it. e.g. number_of_verts = NetworkX.DiGraph.number_of_nodes
.
这篇关于Cython和deepcopy()在引用的方法/功能方面陷入困境。还有其他想法吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!