When pickling a class I get different behavior in python that in cython
我有以下文件层次结构:
1 2 3 4 5 6 | 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中腌制Camera,我得到以下异常:
pickle.PicklingError:不能发泡:它没有被发现为geometry.Camera
但是,如果我删除geometry.pyd而我导入python版本(geometry.py),那么我可以从A.py或B.py中腌制相机。除了删除geometry.pyd,同样的python命令行,在两种情况下从同一文件夹运行都没有别的变化。
为什么这个区别?
挖掘一下,我发现异常发生在C: Python27 Lib pickle.py第742行
1 2 3 4 5 6 7 8 | 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),(我挑选一个Camera实例来触发预期)模块是"几何",
我已经通过将python / geometrylib添加到PYTHONPATH解决了这个问题,然后我可以使用cython版本正确地从A.py和B.py中选择Camera。
这是怎么回事?我不喜欢我的解决方案。有人有更好的解决方案吗?
已编辑以添加一些额外信息。
另外,根据请求,这是我用来构建cython扩展的setup.py。
1 2 3 4 5 6 7 8 | 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作为顶级模块,而实际上它是
您应该遵循标准的打包指南,即将setup.py放入顶级模块(geometrylib)旁边的"Python"文件夹中。 安装调用将如下所示:
1 2 3 | setup( cmdclass = {'build_ext': build_ext}, ext_modules = [Extension("geometrylib.geometry", ['geometrylib/geometry.pyx'], include_dirs=[numpy.get_include(),"."])]) |