我可以使用以下语法创建多行字符串:
string = str("Some chars "
"Some more chars")
这将会产生以下字符串:
"Some chars Some more chars"
Python是将这两个独立的字符串连接起来,还是编辑器/编译器将它们视为单个字符串?
附注:我只是想了解内部机制。我知道还有其他方法来声明或创建多行字符串。
我可以使用以下语法创建多行字符串:
string = str("Some chars "
"Some more chars")
这将会产生以下字符串:
"Some chars Some more chars"
Python是将这两个独立的字符串连接起来,还是编辑器/编译器将它们视为单个字符串?
附注:我只是想了解内部机制。我知道还有其他方法来声明或创建多行字符串。
允许使用多个相邻的字符串或字节文字(由空格分隔),可能使用不同的引号约定,它们的含义与它们的连接相同。因此,“hello” 'world'等同于“helloworld”。这个特性可以用于减少需要的反斜杠数量,方便地跨越长行拆分长字符串,甚至可以向字符串的部分添加注释。
(我强调了这一点)
这就是为什么:
string = str("Some chars "
"Some more chars")
与 str("一些字符更多的字符")
完全相同。
在任何字符串字面值可能出现的地方都执行此操作,如列表初始化、函数调用(如上述的 str
)等。
唯一的注意事项是当一个字符串字面值不包含在 分组定界符 ()
, {}
或 []
中,而是在两个单独的 物理行 之间扩展时。在这种情况下,我们可以 使用 反斜杠字符来连接这些行并获得相同的结果:
string = "Some chars " \
"Some more chars"
string = "Hello " "World"
就可以了)
Python是将这两个独立的字符串连接起来,还是编辑器/编译器将它们视为单个字符串处理?
Python会将这两个字符串连接起来,但具体是在何时进行这种操作则比较有趣。
据我所知(请注意,我不是解析专家,以下内容可能有误),这种操作发生在Python将给定表达式的解析树(LL(1)
Parser)转换为相应的AST(抽象语法树)时。
您可以通过parser
模块查看解析树。
import parser
expr = """
str("Hello "
"World")
"""
pexpr = parser.expr(expr)
parser.st2list(pexpr)
expr
中解析出的具体语法树:-- rest snipped for brevity --
[322,
[323,
[3, '"hello"'],
[3, '"world"']]]]]]]]]]]]]]]]]],
-- rest snipped for brevity --
这些数字对应于解析树中的符号或标记,符号到语法规则的映射和标记到常量的映射分别在Lib/symbol.py
和Lib/token.py
中。
正如我添加的片段所示,你可以看到与解析的表达式中的两个不同的str
字面值相对应的两个不同条目。
接下来,我们可以通过标准库中提供的ast
模块查看前面表达式生成的AST树的输出:
p = ast.parse(expr)
ast.dump(p)
# this prints out the following:
"Module(body = [Expr(value = Call(func = Name(id = 'str', ctx = Load()), args = [Str(s = 'hello world')], keywords = []))])"
args
是单个连接字符串Hello World
。ast
节点的树形可视化。使用它,表达式expr
的输出像这样可视化:
图片被裁剪以仅显示表达式的相关部分。
正如您所看到的,在终端叶节点中,我们有一个单独的str
对象,即连接"Hello "
和"World"
的字符串,即"Hello World"
。
Parser/pgen.c
,而将解析树转换为抽象语法树的代码位于Python/ast.c
。Python 3.5
,我非常确定除非你使用一些非常旧的版本(< 2.5
),否则功能和位置应该是类似的。str
,而不是括号:("一些字符" "更多字符")
。 - falsetruPython
的c
源代码是我目前还没有完全掌握技能的事情(很快就会了!)。 - Dimitris Fasarakis Hilliard
"""
或'''
)来创建多行字符串。 - zvone