当酸洗I类在python得到不同的行为,在用Cython(When pickling a class

2019-09-24 05:39发布

我有以下文件层次:

python/apps/A.py
      /geometrylib/__init__.py
      /geometrylib/B.py
      /geometrylib/geometry.py
      /geometrylib/goemetry.pyx
      /geometrylib/goemetry.pyd

geometry.pyx和geometry.py包含相同类相机(在用Cython版本定义了与所述CDEF类)。 无论A.py和B.py导入几何模块。

如果我在Python / geometrylib文件夹导入用Cython版本(编译geometry.pyd),我能够正确咸菜相机从内部B.py。 但我可以从A.py没有泡菜相机在Python / apps文件夹,我得到以下异常:

pickle.PicklingError:不能咸菜:它没有发现如geometry.Camera

但是,如果我删除geometry.pyd和我导入Python版本(geometry.py)代替,那么我可以从A.py或B.py.咸菜相机 闲来无事从删除geometry.pyd,同巨蟒的命令行,在这两种情况下相同的文件夹中运行的变化分开。 为什么这种差异?

挖了一下我看到,在C出现异常:\ Python27 \ LIB \ pickle.py线742

try:
    __import__(module)            #line 742
    mod = sys.modules[module]
    klass = getattr(mod, name)
except (ImportError, KeyError, AttributeError):
    raise PicklingError(
        "Can't pickle %r: it's not found as %s.%s" %
        (obj, module, name))

当A.py我导入用Cython版本(geometry.pyd),(我腌一个相机例如触发厚望)模块是“几何”和__import__(module)触发例外。 当A.py我导入Python版本(geometry.py),(我腌一个相机例如触发厚望)模块是“geometrylib.geometry”和__import__(module)正确导入模块。

我已经加入蟒蛇/ geometrylib到PYTHONPATH解决了这个问题,那么我就可以从两个A.py和B.py泡菜正确使用相机的用Cython版本。

难道,这就是它应该如何运作? 我不喜欢我的解决方案。 没有任何人有一个更好的解决办法?

编辑以添加一些额外的信息。

此外,通过请求,这是我用于构建用Cython扩展setup.py。

from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
import numpy

setup(
    cmdclass = { 'build_ext': build_ext},
    ext_modules = [Extension("geometry", ['geometry.pyx'], include_dirs=[numpy.get_include(), "."])])

Answer 1:

您正在建设geometry.pyx为顶层模块,而实际上它是一部分geometrylib包。 其结果是, Camera类被分配不正确__module__值( geometry ,而不是geometrylib.geometry ),当它试图找到一个名为顶层模块皮克勒失败geometry

您应该遵循标准包装准则,即把setup.py到“巨蟒”的文件夹,旁边的顶层模块(geometrylib)。 建立呼叫看起来就像这样:

setup(
    cmdclass = {'build_ext': build_ext},
    ext_modules = [Extension("geometrylib.geometry", ['geometrylib/geometry.pyx'], include_dirs=[numpy.get_include(), "."])])


文章来源: When pickling a class I get different behavior in python that in cython