Cython的language_level 3和3str有什么区别?

时间:2019-08-08 14:54:22

标签: python cython

在即将到来的Cython 3.0版本中,3str language_level(由Cython 0.29引入)成为新的默认值,而不是当前的默认2,即,如果未设置language_level({ {3}}),我们收到以下警告:

  

FutureWarning:未设置Cython指令'language_level',使用'3str'   现在(Py3)。这与以前的版本有所不同!文件:   /home/ed/mygithub/cython/foo.pyx tree = Parsing.p_module(s,pxd,   full_module_name)

但是3str3语言级别之间有什么区别,并且对于哪些代码,用3str3语言级别编译的模块的行为会有区别?

2 个答案:

答案 0 :(得分:5)

TLDR: 3str并不认为字符串文字在Python2.x下是统一码,这使得从Python2.x到Python3的迁移更加容易。

不是一个完整的答案,因为我不知道突出差异的代码,并且仍然留有疑问的余地,但这可能很有用,Whats new in cython 0.29

  

新的语言级别'

     

Cython 0.29支持language_level指令language_level=3str的新设置,它将成为Cython 3.0中新的默认语言级别。我们现在已经添加了它,以便用户可以立即加入并从中受益,并且已经为即将发生的更改准备了代码。这是“介于两者之间”的一种设置,它启用与Python 2.x语法不兼容的所有不错的Python 3好东西,但是当编译后的代码在Python中运行时,不需要所有未加前缀的字符串文字成为Unicode字符串。 2.x 。这是一般Py3迁移中的最大问题之一。在Cython与C代码集成的上下文中,它给我们的用户带来的障碍甚至比Python代码多得多。我们的目标是使来自Python 3的新用户可以轻松地使用Cython编译代码,并允许现有的(Cython / Python 2)代码库充分利用这些好处,然后才能进行100%的切换。

也由Debian's manpage for cython指出:

  

--embed[=<method_name>]生成一个main()函数,该函数嵌入了Python解释器。
  -2基于Python-2语法和代码语义进行编译。
  -3基于Python-3语法和代码语义进行编译。
  --3str基于Python-3语法和代码语义进行编译,而对于Python 2下的字符串文字,默认情况下不假定unicode。

最后由cython docs指出:

  

3str选项启用Python 3语义,但是当编译后的代码在Python 2.x中运行时,不会将str类型和未前缀的字符串文字更改为unicode

答案 1 :(得分:2)

language_level用于指示pyx文件写入哪个Python版本。因此,对于language_level=3,即使结果扩展是使用Python2运行的,pyx代码的最终行为也好像是在Python3中执行的(请参见更详细的解释here)。

语言级别3str的意思是“ Python3语义,但具有str文字(在Python2.7中也是)”-因此名称中的str。到底有什么后果?

Python3::为Python3内置/为Python3时,级别3和级别3str之间没有区别。

在Python3中,strunicode,所以类型

# foo.pyx
def test():
   return type("aaa")

对于strlanguage_level=3将保持相同(language_level=3str)。

Python2 :使用Python2或为Python2构建时的情况有所不同。使用language_level=3时,以上test函数的结果将为unicode,使用language_level=3str时,结果将为str(在Python2中为字节)。而且对于Python2,在所有其他情况下,33str的行为相同。


认为,这将是一个错误

cdef char *c_string = "some string"

将无法使用language_level=3构建(而对于Python2,则无法使用3str构建成功,因为“某些字符串”为bytes),因为"some string"是Unicode和Unicode文字只能被强制为Py_UNICODE*

右侧的文字不是开头的Python对象,而只是生成的C代码中的C字符串。