Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/353.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
在pickle类时,python中的行为与cython中的不同_Python_Import_Pickle_Cython - Fatal编程技术网

在pickle类时,python中的行为与cython中的不同

在pickle类时,python中的行为与cython中的不同,python,import,pickle,cython,Python,Import,Pickle,Cython,我有以下文件层次结构: python/apps/A.py /geometrylib/__init__.py /geometrylib/B.py /geometrylib/geometry.py /geometrylib/goemetry.pyx /geometrylib/goemetry.pyd geometry.pyx和geometry.py包含相同的类Camera(cython版本使用cdef定义该类)。A.py和B.py都导入几

我有以下文件层次结构:

python/apps/A.py
      /geometrylib/__init__.py
      /geometrylib/B.py
      /geometrylib/geometry.py
      /geometrylib/goemetry.pyx
      /geometrylib/goemetry.pyd
geometry.pyx和geometry.py包含相同的类Camera(cython版本使用cdef定义该类)。A.py和B.py都导入几何体模块

如果我导入cython版本(编译为geometry.pyd),我就可以从python/geometrylib文件夹的B.py中正确地pickle Camera。但我无法从python/apps文件夹中的A.py中pickle Camera,我得到以下异常:

pickle.PicklingError:无法pickle:找不到它作为几何体。摄影机

但是,如果删除geometry.pyd并导入python版本(geometry.py),则可以从A.py或B.py中pickle摄影机。除了删除geometry.pyd(在这两种情况下从同一文件夹运行的同一python命令行)之外,没有其他更改。 为什么会有这种差异?

稍微挖掘一下,我发现异常发生在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),(我通过pickle一个摄影机实例来触发expection)模块是“geometry”,并且
\uuuuuuu import\uuuu(module)
触发异常。在A.py中,我导入python版本(geometry.py),(并通过pickle一个摄影机实例来触发expection)模块是“geometrylib.geometry”,并且
\uu导入\uuuuuuuuu(模块)
正确导入模块

我通过向PYTHONPATH添加python/geometrylib解决了这个问题,然后我可以使用cython版本正确地从A.py和B.py中pickle摄影机

这就是它的工作原理吗?我不喜欢我的解决方案有谁有更好的解决方案吗?

编辑以添加一些额外信息

另外,根据请求,这是我用来构建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(), "."])])

您正在将geometry.pyx构建为顶级模块,而实际上它是
geometrylib
包的一部分。结果,
Camera
类被分配了不正确的
\uuuuu模块
值(
geometry
而不是
geometrylib.geometry
),pickler在尝试查找名为
geometry
的顶级模块时失败

您应该遵循标准的打包准则,即将setup.py放入顶层模块(geometrylib)旁边的“Python”文件夹中。安装调用将如下所示:

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

当您执行Cython版本和纯Python版本时,Python命令行是什么样子的?您在哪个目录下执行Python命令?[未完成就意外点击enter]您是如何编译Cython模块的?请记住:Cython文件通常编译到不同的目录中,因此您需要告诉它在哪里可以找到正在导入的其余模块。也许你可以在
setup.py
中这样做,但老实说,如果没有任何其他信息,我无法告诉你。谢谢你的评论,请参阅我的上述编辑。这解决了问题!我不知道这是标准的包装指南,我要读一下!