【问题标题】:What does language_level in setup.py for cython do?cython 的 setup.py 中的 language_level 有什么作用?
【发布时间】:2019-02-27 08:06:50
【问题描述】:

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

最终的结果完全一样吗?

【问题讨论】:

标签: cython


【解决方案1】:

构建 cython 扩展是一个两步过程:

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

生成的扩展可以与 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)

所以你can explicitly set the language_level,这样你的扩展程序具有相同的行为,独立于它被 cython 化的 Cython 版本。

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

使用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!

显然以上只是两个例子,还有很多不同之处(例如str & unicode 的东西)。


另一个显着的区别是Python3 disablesimplicit relative imports,这意味着在包内部,我们不再 cimport 使用隐式相对导入

# works with language_level=2
cimport other_local_cymodule

但使用显式相对导入

 # works with language_level=3,3str
 from . cimport other_local_cymodule

或绝对导入

 # works with language_level=3,3str
 cimport package.other_local_cymodule

一般来说,我会尽量避免混合使用不同的 language_level 和 Python-interpreter-version,因为这会导致违反直觉的行为。

例如在下面的例子中混合language_level=2和Python3:

%%cython -2
def divide2(int a, int b):
    return a/b

def divide3(a, b):
    return a/b

>>> divide2(2,3), divide3(2,3)
# (0, 0.66666666) 

对于函数divide2,Cython 可以确保“正确”的 Python2-behavior,但如何进行除法取决于 int-object 的行为,它具有正常的 Python3-behavior。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-10-12
    • 2014-03-16
    • 2012-12-09
    • 1970-01-01
    • 2016-10-18
    • 2014-01-26
    • 1970-01-01
    相关资源
    最近更新 更多