使用其他python版本或在其他操作系统上导入cython生成的*.so-module

2022-03-01 00:00:00 python cython shared-libraries

问题描述

如何在python中导入文件myModule.cpython-35m-x86_64-linux-gnu.so?有可能吗?

我尝试了常规方式:

import myModule

翻译说:

`ModuleNotFoundError: No module named 'myModule'`

这是一个我无法在我正在工作的群集中安装的软件,所以我只是解压缩了.deb程序包,它没有要安装的轮文件或结构。

Python

在一个推荐答案版本中使用为另一个Python版本构建的C扩展是有问题的。通常(至少对于Python3)存在一种机制来区分不同Python版本的C扩展,因此它们可以共存于同一目录中。

在您的示例中,后缀是cpython-35m-x86_64-linux-gnu,因此x86_64Linux上的CPython3.5将选择此C扩展。如果您尝试使用另一个Python版本或在另一个平台上导入此扩展,该模块将不可见,并且会引发ModuleNotFoundError

可以查看当前Python版本接受哪些后缀,例如VIA:

>>> import _imp
>>>_imp.extension_suffixes()
['.cpython-36m-x86_64-linux-gnu.so', '.abi3.so', '.so']

一种可能是使用稳定的C-API,它可以与多个Python版本一起使用,而无需重新编译。Cython开始在3.0版本中支持它(请参阅this PR),也请参阅SO-post关于setuptools和稳定的C-API。

您可能想要聪明一点,将扩展重命名为Simple.so,这样Finder就可以提取它-这可以/确实适用于某些平台上某些扩展的某些Python版本组合-但是这种方法不能长期持续,不是正确的做法。

正确的做法是在正确的操作系统/平台上使用正确的Python版本构建C扩展,或者使用正确的轮子(或使用稳定的C-API)。


一般说来,为python版本(比方说PythonA.B)构建的C扩展不能由另一个Python版本(比方说PythonC.D)使用,因为这些扩展/模块链接到一个特殊的Python库,并且所需的功能可能不再/还不存在于另一个版本的库中。

这不同于*.py-文件,更类似于*.pyc-不能与其他版本一起使用的文件。

PEP-3147规定的是*.pyc文件,而PEP-3149则是对C扩展执行相同的操作。PEP-3149不是最先进的,因为有些问题只解决了in Python3.5,可以找到整个讨论here。

相关文章