如何在Cython的setup.py中指定Python 3源?

rst*_*ard 15 python cython python-3.x

我正在尝试根据本教程http://docs.cython.org/src/tutorial/cython_tutorial.html#cython-hello-world在Cython中创建“ Hello World”程序

我创建了helloworld.pyx

print("Hello World")
Run Code Online (Sandbox Code Playgroud)

和setup.py:

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

setup(
    ext_modules = cythonize("helloworld.pyx")
)
Run Code Online (Sandbox Code Playgroud)

如何更改setup.py以指定源是Python 3,而不是本教程中的Python 2?如果我从命令行调用“ cython”命令,它将接受-3选项。但是,如果我python setup.py build_ext --inplace按照本教程中所示进行编译,该如何指定Python 3源?对于Hello World程序来说,它可能无关紧要,但是随着我开始在实际项目中使用Cython时,它会变得很重要。

非常感谢!

Gal*_*and 24

如果您使用带有扩展名的 setup.py,如本例所示

from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext

ext_modules = [
    Extension("mymodule1",  ["mymodule1.py"]),
    Extension("mymodule2",  ["mymodule2.py"]),
]

setup(
    name = 'My Program Name',
    cmdclass = {'build_ext': build_ext},
    ext_modules = ext_modules
)
Run Code Online (Sandbox Code Playgroud)

然后您必须添加以下代码段以应用 language_level 指令(在 setup(...) 之前,感谢 codeman48):

for e in ext_modules:
    e.cython_directives = {'language_level': "3"} #all are Python-3
Run Code Online (Sandbox Code Playgroud)

  • 当循环放置在 `ext_modules = [...]` 内容之后和 `setup(...` 内容之前) 时,此方法有效。谢谢! (3认同)

ead*_*ead 21

可以将language_level一个选项作为选项传递给-script cythonize中的setup.py-function:

extensions = cythonize(extensions, compiler_directives={'language_level' : "3"})) # or "2" or "3str"
Run Code Online (Sandbox Code Playgroud)

还是应该将该脚本解释为language_level=2Python2和language_level=3Python3(在IPython中,%% cython-magic的行为):

import sys
# passing 3 or 2 as integer is also accepted:
cythonize(extensions, compiler_directives={'language_level' : sys.version_info[0]})
Run Code Online (Sandbox Code Playgroud)

另一种可能的语法是

extensions = cythonize(extensions, language_level = "3")
Run Code Online (Sandbox Code Playgroud)

以上可能比添加更方便

#cython: language_level=3
Run Code Online (Sandbox Code Playgroud)

到项目中的每个pyx文件,这可能是必要的,因为自Cython 0.29以来就有警告,如果language_level 未明确设置

/Main.py:367:FutureWarning:未设置Cython指令'language_level',现在使用2(Py2)。这将在以后的版本中更改!档案:XXXXXX.pyx
tree = Parsing.p_module(s, pxd, full_module_name)


因为language_level是全局设置,所以装饰器

cimport cython

@cython.language_level("3")
def do_something():
    pass
Run Code Online (Sandbox Code Playgroud)

甚至不会被cythonized。


小智 10

根据有关编译的官方文档,可以使用指令通过文件顶部的特殊标头注释来指定Python语言级别,如下所示:

#!python
#cython: language_level=3
Run Code Online (Sandbox Code Playgroud)

似乎没有办法在setup.py中指定它。因此,如果您有许多Cython文件,则必须在每个文件中添加编译器指令。尽管到目前为止,我遇到的唯一需要此指令的情况就是您的示例中的print(),并且我已经广泛使用了Cython。