あなたのモジュールのsetup.py
と__init__
ファイルの両方で何らかの変更を加えなければならないと思います。
レッツは、あなたのパッケージの名前は、「モジュール」になりますと言うと、あなたがsub
サブフォルダ内の純粋なPythonのコードとc_sub
サブフォルダに同等のCコードを持ってsub
いる機能を、持っています。あなたの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)
class BuildFailed(Exception):
pass
def construct_build_ext(build_ext):
class WrappedBuildExt(build_ext):
# This class allows C extension building to fail.
def run(self):
try:
build_ext.run(self)
except DistutilsPlatformError as x:
raise BuildFailed(x)
def build_extension(self, ext):
try:
build_ext.build_extension(self, ext)
except ext_errors as x:
raise BuildFailed(x)
return WrappedBuildExt
setup_args = {'name': 'module', 'license': 'BSD', 'author': 'xxx',
'packages': ['module', 'module.sub', 'module.c_sub'],
'cmdclass': {}
}
ext_modules = [Extension("module.c_sub._sub", ["module/c_sub/_sub.c"])]
cmd_classes = setup_args.setdefault('cmdclass', {})
try:
# try building with c code :
setup_args['cmdclass']['build_ext'] = construct_build_ext(build_ext)
setup(ext_modules=ext_modules, **setup_args)
except BuildFailed 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 'build_ext' in cmd_classes:
del cmd_classes['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を提供すると仮定します。
このようにしてexample of setup fileがShapely
パッケージにあります。実際に私が投稿したコードのほとんどは、このファイルからコピーされたものです(construct_build_ext
関数)。
出典
2017-01-21 23:42:17
mgc
これはどのように適用されるのかわかりません。彼らはPythonモジュールとしてcythonをインポートしようとし、インポートが失敗した場合はCモジュールにフォールバックします。私はどのように私はPythonでシステムのCコンパイラをインポートしようとするとお勧めしますか? – ARF
実際、少し早期に結論に飛びついた。 –