Python中x='y' 'z'的实现原理是什么?

37
如果在Python中运行x = 'y' 'z',则会得到 x 设置为 'yz',这意味着当 Python 看到多个字符串相邻时,会发生某种字符串连接。

但是这是什么样的连接方式? 它实际上是否在运行'y' + 'z'或者运行''.join('y','z')或其他一些方式?

10
我认为这是词法分析器/语法分析器的一部分。当Python解析文件并看到相邻的字符串时,它将其视为一个单独的字符串。 - univerio
1
如果'x' + 'y'''.join(..)语句之间有差异,您可以尝试看看是否会得到不同的结果。例如,如果您加入一个变量会发生什么? - Jongware
你有一个误解,认为当Python执行任务时,必须使用Python的结构。 - Jim Balter
2个回答

58
The Python解析器将其解释为一个字符串。这在词法分析文档中有详细记录:
字符串字面值连接
允许多个相邻的字符串字面值(由空格分隔),可能使用不同的引号约定,并且它们的含义与它们的连接相同。因此,"hello"'world'等效于"helloworld"。
编译后的Python代码只看到一个字符串对象;您可以通过请求Python生成这些字符串的AST来查看这一点。
>>> import ast
>>> ast.dump(ast.parse("'hello' 'world'", mode='eval').body)
"Str(s='helloworld')"

事实上,正是构建抽象语法树的行为触发了连接操作,当遍历解析树时,可以查看AST C源代码中的parsestrplus()函数
该功能旨在减少反斜杠的使用;在逻辑行内仍然可以使用它来跨物理行拆分字符串,具体请参见逻辑行
print('Hello world!', 'This string is spans just one '
      'logical line but is broken across multiple physical '
      'source lines.')

使用括号、方括号或花括号,可以将多个物理行 隐式合并 成为一行。

这个 字符串连接特性 是从C语言中复制过来的,但是Guido van Rossum曾经后悔将其添加到Python中。这篇文章引发了一个漫长而非常有趣的讨论,很多人支持彻底删除该功能。


3
它适用于同一“逻辑”行上的字符串。如果涉及反斜杠、括号或方括号,该行可以跨越多个物理行。 - Martijn Pieters
1
请注意,源代码中相邻字符串的串联在很大程度上是C族语言的传统。 - Russell Borogove
1
@RussellBorogove:确实,由于它在Python中没有像在C语言中(用于宏)那样的优势,因此它在Python中的日子看来已经不多了。 - Martijn Pieters
1
嗯,我个人认为字面串联不会被移除;至少在未来几年内不会。如果他们想要移除它,应该在制作Python3.0时就这样做了。现在,由于许多人已经在与向后兼容性作斗争,引入其他的破坏可能会使情况变得更糟。它们可能会在发布Python4.0时被移除... - Bakuriu
1
@Bakuriu:实际上,我对Guido在那个帖子中坚决支持删除它感到惊讶,因为6年前已经有一个完整的PEP(从Python 3中删除它)被拒绝了。 - Martijn Pieters
显示剩余5条评论

8

在执行之前,Python解析器会先将字符串连接起来,因此它并不像'y' + 'z'''.join('y','z')那样,但实际效果相同。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接