在运行时编译Python扩展模块

时间:2017-08-28 15:53:50

标签: python

假设我有一个Python函数,它生成并以字符串形式返回扩展模块的C代码。现在我想在运行时将这个C代码编译成.so / .pyd扩展模块,以便我可以导入它。

我该怎么做?

似乎应该可以使用setuptoolsdistutils来实现此目的,因为setup.py本身只是一个普通的Python脚本。但是,这些包会执行许多与安装,依赖性检查等相关的额外操作。是否有任何直接的API挂钩可以让我简单地编译一个扩展模块?

1 个答案:

答案 0 :(得分:0)

我在PyStan项目中找到了相关代码, 具体来说,在pystan.model模块中,它基本上完全符合我的需要。我将这里的代码片段放在后代。下面甚至可以处理Cython扩展,但如果你不需要它,它可以很容易地适应去除Cython依赖。

test_list_of_genes:

AGRN
B3GALT6
TP73

test_bed_file (4 columns tab delimited):

chr1    989121  989367  AGRN.chr1.989132.989357
chr1    989816  989941  AGRN.chr1.989827.989931
chr1    990192  990371  AGRN.chr1.990203.990361
chr1    1146926 1147015 TNFRSF4.chr1.1146938.1147005
chr1    1147072 1147222 TNFRSF4.chr1.1147084.1147212
chr1    1147310 1147528 TNFRSF4.chr1.1147322.1147518
chr1    1167647 1168655 B3GALT6.chr1.1167659.1168645
chr1    1266714 1266926 TAS1R3.chr1.1266726.1266916
chr1    1267006 1267328 TAS1R3.chr1.1267018.1267318
chr1    1267392 1268196 TAS1R3.chr1.1267404.1268186
chr1    3645879 3646022 TP73.chr1.3645891.3646012
chr1    3646552 3646722 TP73.chr1.3646564.3646712
chr1    3647479 3647639 TP73.chr1.3647491.3647629
chr1    3648015 3648130 TP73.chr1.3648027.3648120
chr1    3649299 3649650 TP73.chr1.3649311.3649640
chr1    5923313 5923475 NPHP4.chr1.5923324.5923465

test_results:

chr1    989121  989367  AGRN.chr1.989132.989357
chr1    989816  989941  AGRN.chr1.989827.989931
chr1    990192  990371  AGRN.chr1.990203.990361
chr1    1167647 1168655 B3GALT6.chr1.1167659.1168645
chr1    3645879 3646022 TP73.chr1.3645891.3646012
chr1    3646552 3646722 TP73.chr1.3646564.3646712
chr1    3647479 3647639 TP73.chr1.3647491.3647629
chr1    3648015 3648130 TP73.chr1.3648027.3648120
chr1    3649299 3649650 TP73.chr1.3649311.3649640

编译完成后,您可以通过将模块放入路径(或将其路径添加到from distutils.core import Extension import Cython from Cython.Build.Inline import _get_build_extension from Cython.Build.Dependencies import cythonize # you can add include_dirs= and extra_compile_args= here extension = Extension(name='mymodule', language='c++', sources=[srcfile]) build_extension = _get_build_extension() build_extension.extensions = cythonize([extension], include_path=[], quiet=False) build_extension.build_temp = os.path.dirname(srcfile) build_extension.build_lib = build_dir # where you want the output build_extension.run() )并调用sys.path来加载模块。