Python中长字符串的多行定义方法

Python中长字符串的多行定义方法

技术背景

在Python编程中,我们常常会遇到需要处理长字符串的情况,比如构建复杂的SQL查询语句。为了提高代码的可读性,我们希望将长字符串拆分成多行来定义。然而,Python的语法规则与其他一些编程语言有所不同,不能简单地直接换行。因此,我们需要掌握一些特定的方法来实现长字符串的多行定义。

实现步骤

1. 使用三引号

三引号('''""")可以用来创建多行字符串。示例如下:

1
2
3
s = """ this is a very
long string if I had the
energy to type more and more ..."""

这样定义的字符串会包含换行符和空格。如果不需要换行符,可以使用字符串的 replace 方法进行处理:

1
2
3
4
5
string = """This is a
very long string,
containing commas,
that I split up
for readability""".replace('\n',' ')

2. 使用括号包裹

将多个字符串用括号包裹起来,Python会自动将它们连接起来。示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
query = ('SELECT   action.descr as "action", '
'role.id as role_id,'
'role.descr as role'
' FROM '
'public.role_action_def,'
'public.role,'
'public.record_def, '
'public.action'
' WHERE role.id = role_action_def.role_id AND'
' record_def.id = role_action_def.def_id AND'
' action.id = role_action_def.action_id AND'
' role_action_def.account_id = '+account_id+' AND'
' record_def.account_id='+account_id+' AND'
' def_id='+def_id)

这种方法不会引入额外的换行符和空格,但需要注意在需要空格的地方手动添加。

3. 使用反斜杠 \ 进行行延续

在每行的末尾添加反斜杠 \,可以将字符串延续到下一行。示例如下:

1
2
3
4
longStr = "This is a very long string " \
"that I wrote to help somebody " \
"who had a question about " \
"writing long strings in Python"

4. 使用 join 方法

可以使用 join 方法将多个字符串连接起来。示例如下:

1
2
3
4
5
query = ' '.join((
"SELECT foo",
"FROM bar",
"WHERE baz",
))

5. 使用 f-string(Python 3.6+)

对于需要插入变量的情况,可以使用 f-string。示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
query = f'''SELECT   action.descr as "action"
role.id as role_id,
role.descr as role
FROM
public.role_action_def,
public.role,
public.record_def,
public.action
WHERE role.id = role_action_def.role_id AND
record_def.id = role_action_def.def_id AND
action.id = role_action_def.action_id AND
role_action_def.account_id = {account_id} AND
record_def.account_id = {account_id} AND
def_id = {def_id}'''

6. 使用 textwrap.dedentinspect.cleandoc

当使用三引号定义的字符串有多余的缩进时,可以使用 textwrap.dedentinspect.cleandoc 来去除多余的缩进。示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import textwrap
import inspect

code_snippet = textwrap.dedent("""\
int main(int argc, char* argv[]) {
return 0;
}
""")

query = inspect.cleandoc(f'''
SELECT action.descr as "action",
role.id as role_id,
role.descr as role
FROM
public.role_action_def,
public.role,
public.record_def,
public.action
WHERE role.id = role_action_def.role_id AND
record_def.id = role_action_def.def_id AND
action.id = role_action_def.action_id AND
role_action_def.account_id = {account_id} AND
record_def.account_id={account_id} AND
def_id={def_id}'''
)

核心代码

以下是一个完整的示例,展示了如何使用不同的方法定义长字符串:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 使用三引号
s1 = """This is a
multi-line string."""

# 使用括号包裹
s2 = ("This is a "
"long string.")

# 使用反斜杠
s3 = "This is a very long string " \
"that spans multiple lines."

# 使用 join 方法
s4 = ' '.join([
"This is a",
"long string",
"created using join."
])

# 使用 f-string
name = "John"
s5 = f"Hello, {name}! This is a long string."

print(s1)
print(s2)
print(s3)
print(s4)
print(s5)

最佳实践

  • 可读性优先:选择最适合代码上下文和易于阅读的方法。例如,对于SQL查询,使用三引号或括号包裹的方法可以使查询结构更清晰。
  • 避免SQL注入:在构建SQL查询时,尽量使用参数化查询,避免直接拼接用户输入的变量。例如,使用Python的 sqlite3 模块:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import sqlite3

account_id = 123
def_id = 321

query = '''
SELECT
action.descr as action,
role.id as role_id,
role.descr as role
FROM
public.role_action_def,
public.role,
public.record_def,
public.action
WHERE
role.id = role_action_def.role_id
AND record_def.id = role_action_def.def_id
AND action.id = role_action_def.action_id
AND role_action_def.account_id = ?
AND record_def.account_id = ?
AND def_id = ?
'''
vars = (account_id, account_id, def_id)

conn = sqlite3.connect('example.db')
cursor = conn.cursor()
cursor.execute(query, vars)
results = cursor.fetchall()
conn.close()
  • 遵循PEP 8规范:PEP 8建议使用括号来进行行延续,避免使用反斜杠。

常见问题

1. 忘记添加空格

在使用括号包裹字符串时,如果忘记在需要的地方添加空格,会导致字符串连接在一起。例如:

1
2
3
4
query = ("SELECT foo"
"FROM bar"
"WHERE baz")
# 结果为 "SELECT fooFROM barWHERE baz"

解决方法是在需要空格的地方手动添加空格。

2. SQL注入风险

直接拼接用户输入的变量到SQL查询中会导致SQL注入风险。例如:

1
2
account_id = "1; DROP TABLE users; --"
query = f"SELECT * FROM users WHERE account_id = {account_id}"

解决方法是使用参数化查询,如上述示例中的 sqlite3 模块。

3. 多余的缩进问题

使用三引号定义的字符串可能会包含多余的缩进,影响字符串的实际内容。可以使用 textwrap.dedentinspect.cleandoc 来解决这个问题。


Python中长字符串的多行定义方法
https://119291.xyz/posts/2025-04-14.python-long-string-multiline-definition/
作者
ww
发布于
2025年4月14日
许可协议