Python 字符串文字连接

问题描述 投票:0回答:1

我可以使用以下语法创建多行字符串:

string = str("Some chars "
         "Some more chars")

这将产生以下字符串:

"Some chars Some more chars"

Python 是连接这两个单独的字符串还是编辑器/编译器将它们视为单个字符串?

P.s:我只是想了解内部原理。我知道还有其他方法来声明或创建多行字符串。

附注二:

这也是有效的:

string = str('''Some chars '''
         "Some more chars"'-otherchar')

输出:

Some chars Some more chars-otherchar
python string python-2.7 python-internals
1个回答
36
投票

阅读参考手册就在那里。 具体来说:

允许使用多个相邻的字符串或字节文字(由空格分隔),可能使用不同的引用约定,并且它们的含义与其串联相同。因此,“hello”“world”相当于“helloworld”。 此功能可用于减少所需的反斜杠数量,方便地跨长行分割长字符串,甚至可以为部分字符串添加注释,

强调我的

这就是原因:

string = str("Some chars "
         "Some more chars")

与:

str("Some chars Some more chars")
完全相同。

只要出现字符串文字、列表初始化、函数调用(如上面

str
的情况)等,都会执行此操作。

唯一需要注意的是,字符串文字包含在分组分隔符

()
{}
[]
之一之间,而是分布在两个单独的物理线之间。在这种情况下,我们可以选择使用反斜杠字符来连接这些行并获得相同的结果:

string = "Some chars " \
         "Some more chars"

当然,在同一物理行上串联字符串不需要反斜杠。 (

string = "Hello " "World"
就可以了)


Python 是连接这两个单独的字符串还是编辑器/编译器将它们视为单个字符串?

Python 是,现在何时 Python 确实做到了这一点,这就是事情变得有趣的地方。

据我所知(对此持保留态度,我不是解析专家),当Python将给定表达式的解析树(

LL(1)
解析器)转换为它时,就会发生这种情况对应的 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

此外,我还偶然发现了一个很酷的 module,它可以为

ast
节点生成树的可视化。使用它,表达式
expr
的输出可视化如下:

                                           

图像被裁剪以仅显示表达式的相关部分。

如您所见,在终端叶节点中,我们有一个

str
对象,即
"Hello "
"World"
的连接字符串,即
"Hello World"


如果你足够勇敢,请深入研究源代码,将表达式转换为解析树的源代码位于

Parser/pgen.c
,而将解析树转换为抽象语法树的代码位于
 Python/ast.c
.

此信息适用于

Python 3.5
,我很确定除非您使用某些非常旧的版本(
< 2.5
),否则功能和位置应该是相似的。

此外,如果您对 python 接下来的整个编译步骤感兴趣,核心贡献者之一 Brett Cannon 在视频从源代码到代码:CPython 编译器如何工作中提供了很好的温和介绍。

© www.soinside.com 2019 - 2024. All rights reserved.