动态编译

Dynamic on the fly compile

我有单独的函数(来自用户输入)用于绘图 (x^2, e^x, x, ...),我会在 cython 中计算坐标。 我用 exec 在 Python 代码中创建了一个单独的函数,但这对我来说太慢了。

我尝试生成单独的 .pyx 文件并将它们编译为 .pyd 文件(在 Windows)。

这是我生成单个 .pyx 文件并编译它们的方法。生成工作正常,但只有当我没有从主脚本的 .pyd 文件中导入 cython 模块时,我才能编译它们。如果我编译它然后将模块导入到我的主 class 中,它工作正常,但是一旦导入,我就不能再编译它了。 (该文件用于测试,没有存储 x 或 y 值)

def build(function):
    # code for .pyx file
    code = """cpdef long double computeIt(long double count):
    cdef long double i = 0
    cdef long double result = 0
    for i from 0 <= i < count:
        result = _compute(i)
    return result

cpdef long double compute(long double x):
    return _compute(x)
cdef long double _compute(long double x):
    return """ + function
    # end of code

    with open("evalTest.pyx", "w+") as file:
        file.truncate()
        file.write(code)

    os.system("python setup.py build_ext --inplace") # run setup file

setup.py 文件编译.pyx:

from distutils.core import setup
from Cython.Build import cythonize

setup(
    ext_modules = cythonize("evalTest.pyx")
)

我还尝试将其编译为临时文件并用原子操作替换 .pyd 文件,但随后出现 "Permission denied" 错误(如果我 运行 脚本作为管理员) .

如果我先导入 cython 模块然后尝试重新编译它,我得到:

LINK : fatal error LNK1104: cannot open file 'C:\Users\Alexander\Desktop\onTheFlyCythonCompile\evalTest.cp36-win_amd64.pyd'

error: command 'C:\Program Files (x86)\Microsoft Visual Studio17\Community\VC\Tools\MSVC.11.25503\bin\HostX86\x64\link.exe' failed with exit status 1104

我认为解释器持有该模块,但我无法访问它,但我不知道那是否正确。我也尝试取消链接文件。

有什么解决这个问题的建议吗?

你是对的,解释器保留了 pyd。据我所知,实际上不可能在 运行 python 解释器中卸载 c-extension 模块。

可能处理此问题的最佳方法是随机化/散列化/某种其他类型的唯一文件名。这就是 jupyter 中的 %%cython 魔法所做的。

In [94]: import cython

In [95]: %load_ext cython

In [96]: %%cython
    ...: def f(a, b):
    ...:     return a + b
# generates ~/.ipython/cython/_cython_magic_5a675eece0e27eef1233e0a3e4d811e5.cp36-win_amd64.pyd

也可以看看numba - on-the-fly代肯定更方便。

你也可以使用pyximport

import pyximport; pyximport.install()
Out[13]: (None, <pyximport.pyximport.PyxImporter at 0x101c7c650>)

import computeIt

代码更改后:

reload(computeIt)