cython的setup.py中的language_level有什么作用? [英] What does language_level in setup.py for cython do?
问题描述
如果我在 ext_modules = cythonize(extensions,language_level = 2)
中设置 language_level = 2
更改?仅仅是我编写的代码应该解释为Python2?
If I set language_level=2
in ext_modules = cythonize(extensions, language_level=2)
, what does that change? Is it just that the code I have written should be interpreted as Python2?
最终结果是否完全相同?
Is the end result exactly the same?
推荐答案
建立cython扩展程序分为两个步骤:
Building a cython extension is a two-step proccess:
- 创建<$使用PythonX + cython-module的
foo.pyx
文件中的c $ c> foo.c 文件。X
可以是2.7、3.7,也可以是您喜欢的任何版本。 - 使用以下命令创建相应的so-file(或Windows上的pyd)编译器的帮助,包括PythonY和相应的共享库。在这里
Y
不必是X
,但在大多数情况下是Y
和X
相同。
- creating the
foo.c
-file fromfoo.pyx
file using PythonX+cython-module.X
could be here 2.7, 3.7 or whatever version you prefer. - creating the corresponding so-file (or pyd on Windows) with help of compiler and includes of PythonY and corresponding shared library. Here
Y
doesn't have to beX
, but in most casesY
andX
are the same.
生成的扩展名可以与PythonY一起使用( X
不起作用)。
The resulting extension can be used with PythonY (it doesn't play a role what X
was).
但是,仍然有问题:原始的 pyx
文件写在哪个Python版本中?如果未设置 language_level
,则当前的Cython版本将pyx文件假定为版本 2
(btw对于IPython-%% cython-magic来说不是这种情况,其中文件 foo.c
的版本被cythonized)。
However, there is still the question: In which Python-version was the original pyx
-file written? If language_level
is not set, current Cython-versions assume that the pyx-file was written in the version 2
(btw. this is not the case for IPython-%%cython-magic, where the version with which the file foo.c
is cythonized).
这种行为将来会改变,这就是如果您使用 cython> = 0.29
进行构建时会看到有点恼人的警告的原因:
This behavior will change in the future, this is the reason you see the somewhat irritating warning, if you build with 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
,以便您的扩展名具有与Python版本无关的相同行为,
So you can explicitly set the language_level
, so that your extension has the same behavior independent of the Python-version with which it was cythonized.
有关一些不同行为的示例,请参见下面的示例。
For some examples of different behavior see, the follwoing example.
使用 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
的东西)。
Obviously the above are only two examples, there are much more differences (e.g. str
& unicode
stuff).
其他值得注意的区别之一是 Python3禁用 隐式相对导入,这意味着在包内部,我们不再使用隐式cimport相对导入
One of other notable differences is that Python3 disables implicit relative imports, that means inside of a package, we no longer cimport using implicit relative import
# 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 ,因为它可能导致违反直觉的行为。
In general I would try to avoid mixing different language_level
and Python-interpreter-version, as it can lead to counter-intuitive behavior.
例如,在下面的示例中,混合 language_level = 2
和Python3:
For example in the following example mixing language_level=2
and 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行为正确,但是如何执行除法取决于 int的行为
-object,具有正常的Python3行为。
For the function divide2
Cython can ensure the "right" Python2-behavior, but how the division is performed depends on the behavior of int
-object, which has the normal Python3-behavior.
这篇关于cython的setup.py中的language_level有什么作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!