Python脚本中存在'LF'时的有趣行为,解释器中的错误?

时间:2017-06-16 15:49:47

标签: python

当Python脚本中有+U000a(所谓的'LF')时,会发生一些有趣的事情。

Linux 上,我尝试了几个包含Python2和Python3的案例(见下文),并得出以下结论:

  

'LF'使这条可见行中的连续标记被忽略,但会执行下一行。

是否包含在Python规范中,或者它是解释器中的错误?

对我来说,这至少是解析器的一个问题,因为'LF'不应该具有如上所述的语义;但是日常使用似乎没有什么大问题。

由于'LF'不可打印,我附上截图,其中^@代表'LF'(+ U000a)。对于那些有兴趣尝试的人,我提供了gist(需要git克隆它)。

enter image description here

根据评论更新

import test_2的工作原理与python2 REPL一样,但会在python3中导致ValueError: source code string cannot contain null bytes;直接运行时两者都如上所述。

1 个答案:

答案 0 :(得分:2)

那不是LF U + 000A。这是一个NUL,U + 0000,在^@vimemacs中显示为less - 一个LF会显示为{{1如果它以这种方式显示,但LF显示为换行符。我并不感到惊讶 Python以奇怪的方式处理源代码中的NUL字节,因为在C语言编写的程序中,文本文件中的NUL字节非常常见。 / p>

它似乎是Python解析器本身的缺陷。如果您尝试在Python解释器中复制行为,

^J

您将收到错误消息:

import parser
parser.st2list(parser.expr('"hello"\0"goodbye"'))

对我来说,这表明该行为是无意的,并且从文件加载代码会绕过此检查。我认为这是Python解释器中的一个错误。

仅当有问题的文件是主程序时才会发生这种情况。如果TypeError: expr() argument 1 must be str without null characters, not str 包含NUL字节的文件,则会出错。看来这是因为Python使用import(请参阅tokenizer.c:1022)逐行读取主​​源文件,该文件返回以NUL结尾的字符串。如果该行包含一个NUL字节,它将被截断。