我想为一个项目创建一个包,该项目不包含任何 .py
源文件,但完全实现为 Python C 扩展(导致 .so
)。此外,假设 .so
已经由单独的构建过程(例如 CMake)构建。
我知道 setuptools/distutils 至少需要一个目录结构:
- 我的模块
- __初始化__.py
但我真正想要的是由 C 扩展(比如 mymodule.so
)提供的 mymodule
,这样在安装包之后,import mymodule
与直接导入mymodule.so
效果相同。
我知道我可以有这样的目录结构:
- 我的模块
- __初始化__.py
- mymodule_native.so
并让 __init__.py
成为:
from mymodule_native import *
这种方法可行,但是从 mymodule
导入的对象 A
实际上看起来像 mymodule.mymodule_native.A
。
有没有更直接的方法?
最佳答案
如果扩展由 setuptools 配置是可能的。
例如:
from setuptools import setup, Extension
extension = Extension('mymodule', sources=[<..>])
setup('mymodule', ext_modules=[extension])
安装后,扩展可用 import mymodule
.注意 find_packages
未使用。
这需要由 setuptools 完成,否则需要 packages
如果没有设置 ext_modules
提供。
但是,这使得 .so
模块直接安装在site-packages
下目录并将与任何同名的非扩展 python 模块冲突。
这通常被认为是不好的做法,大多数库使用带有单个 __init__.py
的裸 python 模块。 , 在其下可以使用扩展名。
例如,您将来可能会将 python 代码添加到您的模块中,并希望将纯 python 代码与扩展代码分开。或者您可能想要添加多个扩展,但这种方式是不可能的,至少在保持相同包名的情况下不会。
所以结构像mymodule.<python modules>
和 mymodule.my_extension
说得通。
就我个人而言,我会为扩展代码和 python 代码提供单独的 namespace ,不会做 from <ext mod> import *
在__init__.py
.
关于python - 为预构建的仅 C 扩展模块创建 Python 包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45600987/