我猜你必须在你的 setup.py 和你模块中的一个 __init__ 文件中进行一些修改。
假设您的包的名称将是“模块”,并且您有一个功能,sub,您在 sub 子文件夹中有纯 Python 代码,在 c_sub 子文件夹中有等效的 C 代码。
例如在您的 setup.py 中:
import logging
from setuptools.extension import Extension
from setuptools.command.build_ext import build_ext
from distutils.errors import CCompilerError, DistutilsExecError, DistutilsPlatformError
logging.basicConfig()
log = logging.getLogger(__file__)
ext_errors = (CCompilerError, DistutilsExecError, DistutilsPlatformError, IOError, SystemExit)
setup_args = {'name': 'module', 'license': 'BSD', 'author': 'xxx',
'packages': ['module', 'module.sub', 'module.c_sub'],
'cmdclass': {'build_ext': build_ext}
}
ext_modules = [Extension("module.c_sub._sub", ["module/c_sub/_sub.c"])]
try:
# try building with c code :
setup(ext_modules=ext_modules, **setup_args)
except ext_errors as ex:
log.warn(ex)
log.warn("The C extension could not be compiled")
## Retry to install the module without C extensions :
# Remove any previously defined build_ext command class.
if 'build_ext' in setup_args['cmdclass']:
del setup_args['cmdclass']['build_ext']
# If this new 'setup' call don't fail, the module
# will be successfully installed, without the C extension :
setup(**setup_args)
log.info("Plain-Python installation succeeded.")
现在您需要在您的 __init__.py 文件中(或与您的情况相关的任何位置)包含类似的内容:
try:
from .c_sub import *
except ImportError:
from .sub import *
这样,如果是构建的,将使用 C 版本,否则使用纯 python 版本。它假定sub 和c_sub 将提供相同的API。
您可以在Shapely 包中找到这样做的example of setup file。实际上,我发布的大部分代码都是从该文件中复制(construct_build_ext 函数)或改编(之后的行)。