【问题标题】:cythonize doesn't recopmile a modified pyx file after second call in one runtime在一个运行时第二次调用后,cythonize 不会重新编译修改后的 pyx 文件
【发布时间】:2020-03-29 13:54:55
【问题描述】:

我需要多次生成一个pyx文件并在一个运行时运行它的重新编译并将相应的扩展重新加载到程序中。 这是一个简化的例子:

from setuptools import Extension, setup
from Cython.Build import cythonize
import sys

pyxfile = "foo.pyx"

def write_pyx(incval):
    with open(pyxfile, 'w') as f:
        f.write('cpdef int foo(int x):\n  return x+%i' % incval)

def ext_compile():
    oldargv = sys.argv
    sys.argv = ['thisfile.py', 'build_ext', '--inplace']
    setup(
        ext_modules=cythonize(
            [ Extension("example", [pyxfile]) ],
            compiler_directives={'language_level': 2}
        )
    )
    sys.argv = oldargv

write_pyx(1)
ext_compile()

import example
print "foo(1) =", example.foo(1)

write_pyx(10)
ext_compile()

reload(example)
print "foo(1) =", example.foo(1)

然而,在执行时,尽管 pyx 文件发生了变化,但我只有一个编译。这是控制台的输出:

Compiling foo.pyx because it changed.
[1/1] Cythonizing foo.pyx
running build_ext
building 'example' extension
gcc -pthread -fno-strict-aliasing -g -O2 -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC -I/home/artem/.pyenv/versions/2.7.16/include/python2.7 -c foo.c -o build/temp.linux-x86_64-2.7/foo.o
gcc -pthread -shared -L/home/artem/.pyenv/versions/2.7.16/lib build/temp.linux-x86_64-2.7/foo.o -o build/lib.linux-x86_64-2.7/example.so
copying build/lib.linux-x86_64-2.7/example.so -> 
foo(1) = 2
running build_ext
copying build/lib.linux-x86_64-2.7/example.so -> 
foo(1) = 2

知道如何解决这个问题吗?

【问题讨论】:

标签: python cython cythonize


【解决方案1】:

只有每次我为 pyx 文件和扩展名使用不同的名称时,我才能解决这个问题:

from setuptools import Extension, setup
from Cython.Build import cythonize
import sys
import importlib

def write_pyx(pyxfile, incval):
    with open(pyxfile, 'w') as f:
        f.write('cpdef int foo(int x):\n  return x+%i' % incval)

def ext_compile(extname, pyxfile):
    oldargv = sys.argv
    sys.argv = ['thisfile.py', 'build_ext', '--inplace']
    setup(
        ext_modules=cythonize(
            [ Extension(extname, [pyxfile]) ],
            compiler_directives={'language_level': 2}
        )
    )
    sys.argv = oldargv

pyxfile = "foo01.pyx"
extname = "example01"
write_pyx(pyxfile, 1)
ext_compile(extname, pyxfile)
example = importlib.import_module(extname)

print "foo(1) =", example.foo(1)

pyxfile = "foo10.pyx"
extname = "example10"
write_pyx(pyxfile, 10)
ext_compile(extname, pyxfile)
example = importlib.import_module(extname)

print "foo(1) =", example.foo(1)

输出是:

Compiling foo01.pyx because it changed.
[1/1] Cythonizing foo01.pyx
running build_ext
building 'example01' extension
gcc -pthread -fno-strict-aliasing -g -O2 -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC -I/home/artem/.pyenv/versions/2.7.16/include/python2.7 -c foo01.c -o build/temp.linux-x86_64-2.7/foo01.o
gcc -pthread -shared -L/home/artem/.pyenv/versions/2.7.16/lib build/temp.linux-x86_64-2.7/foo01.o -o build/lib.linux-x86_64-2.7/example01.so
copying build/lib.linux-x86_64-2.7/example01.so -> 
foo(1) = 2
Compiling foo10.pyx because it changed.
[1/1] Cythonizing foo10.pyx
running build_ext
building 'example10' extension
gcc -pthread -fno-strict-aliasing -g -O2 -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC -I/home/artem/.pyenv/versions/2.7.16/include/python2.7 -c foo10.c -o build/temp.linux-x86_64-2.7/foo10.o
gcc -pthread -shared -L/home/artem/.pyenv/versions/2.7.16/lib build/temp.linux-x86_64-2.7/foo10.o -o build/lib.linux-x86_64-2.7/example10.so
copying build/lib.linux-x86_64-2.7/example10.so -> 
foo(1) = 11

【讨论】:

    猜你喜欢
    • 2016-04-07
    • 1970-01-01
    • 2012-09-04
    • 1970-01-01
    • 2019-01-27
    • 1970-01-01
    • 2021-10-22
    • 1970-01-01
    • 2018-04-13
    相关资源
    最近更新 更多