回答问题

我最近一直在玩 Cython 以提高速度,但是我的项目继承了一个模块,该模块具有使用deepcopy()copy()方法。我尝试在copy()的覆盖版本中实现deepcopy(),我认为它可以工作,但它似乎不再可用。

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 中:

return cls.__new__(cls, *args)

我在这里使用 Python 2.7。更新版本的 Python 是否有可能以“安全”的方式从deepcopy()返回?我也在使用最新版本的 Cython,0.15.1。

更新3

请注意,我已删除以前的更新以使其尽可能简单。

好的!我想我发现了不兼容,但我真的不知道该怎么做。

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}

然后在我的主应用程序中:

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 期间爆炸。如果我包含一个,它不喜欢 deepcopy/copy_reg 复制引用的方式。

除了不使用方法/函数引用之外还有什么想法吗?如果这是一个简单的答案,我还有一些事情要做。 (当我完成输入时,我已经在工作了)

谢谢!

Answers

啊,终于找到了“回答你自己的问题”按钮。

我可能不耐烦了,但由于还没有人回复(我的意思是谁在使用 Cython 并在星期四下午回答问题),我想我会关闭这个。

  1. Cython 不喜欢对具有函数/方法引用变量的类进行深度复制。这些变量副本将失败。据我所知,没有办法解决它,你只需要想出一个不需要它们的新设计。我最终在我的项目中使用上面相同的代码这样做了。

  2. Cython 根本不处理属性装饰器。你不能@property@<property name>.setter。属性需要以旧的方式设置。例如<property name> = property(get_property, set_property).

  3. 继承的非 Cython 类的方法“可能”不可访问。我知道这个模糊。我无法完全解释。我要说的是我继承了NetworkX.DiGraph,而number_of_nodes()在Cython之后无法访问,当时它是直接的Python。我必须创建对该方法的引用并使用它。例如number_of_verts = NetworkX.DiGraph.number_of_nodes.

Logo

Python社区为您提供最前沿的新闻资讯和知识内容

更多推荐