cython的setup.py中的language_level有什么作用?

时间:2019-02-27 08:06:51

标签: cython

如果我在language_level=2中设置了ext_modules = cythonize(extensions, language_level=2),那会发生什么变化?只是我编写的代码应该解释为Python2吗?

最终结果是否完全相同?

1 个答案:

答案 0 :(得分:2)

构建cython扩展程序分为两个步骤:

  1. 使用PythonX + cython模块从foo.c文件创建foo.pyx文件。 X可以是2.7、3.7或您喜欢的任何版本。
  2. 在编译器的帮助下创建相应的so文件(或Windows上的pyd),其中包括PythonY和相应的共享库。这里Y不一定是X,但是在大多数情况下,YX是相同的。

生成的扩展名可以与PythonY一起使用(它没有起到X的作用)。

但是,仍然存在一个问题:原始pyx文件是在哪个Python版本中编写的?如果未设置language_level,则当前的Cython版本会假定pyx文件是用版本2编写的(顺便说一句,对于IPython-%% cython-magic来说不是这种情况) foo.c被cythonized)。

这种行为将来会改变,这就是如果您使用cython>=0.29进行构建时会看到有些恼人的警告的原因:

  

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

因此,您可以显式设置language_level,以便您的扩展名具有相同的行为,而与其被cythonized的Python版本无关。

有关不同行为的一些示例,请参见下面的示例。

使用language_level=3

%%cython -3
print("I'm", "not a tuple")
print(5/4) 

产生

I'm not a tuple
1.25  

但使用language_level=2

%%cython -2
print("I'm", "not a tuple")
print(5/4) 

产生

("I'm", 'not a tuple')   # yet a tuple!
1                        # integer division in Python2!

很显然,以上只是两个示例,还有很多区别(例如strunicode的东西)。