我有以下文件层次结构:
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 中正确地腌制相机。但是我不能从 python/apps 文件夹中的 A.py 腌制相机,我得到以下异常:
pickle.PicklingError: Can't pickle : it's not found as geometry.Camera
但是,如果我删除 geometry.pyd 并导入 python 版本(geometry.py),那么我可以从 A.py 或 B.py 腌制相机。除了删除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),(我腌制了一个 Camera 实例以触发期望)模块是“几何”并__import__(module)
触发异常。在 A.py 中,我导入了 python 版本(geometry.py),(并且我腌制了一个相机实例以触发期望)模块是“geometrylib.geometry”并__import__(module)
正确导入模块。
我已经通过将 python/geometrylib 添加到 PYTHONPATH 解决了这个问题,然后我可以使用 cython 版本从 A.py 和 B.py 正确地腌制相机。
这是它应该如何工作的吗?我不喜欢我的解决方案。有人有更好的解决方案吗?
编辑添加一些额外的信息。
此外,根据要求,这是我用来构建 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(), "."])])