如何将长字符串的定义分成多行?
- 2024-11-27 10:43:00
- admin 原创
- 17
问题描述:
我有一个很长的查询。我想在 Python 中将其拆分成几行。在 JavaScript 中执行此操作的一种方法是使用几个句子并用+
运算符将它们连接起来(我知道,这可能不是最有效的方法,但在这个阶段我并不真正关心性能,只是关心代码的可读性)。示例:
var long_string = 'some text not important. just garbage to' +
'illustrate my example';
我尝试在 Python 中做类似的事情,但没有成功,所以我习惯于``拆分长字符串。但是,我不确定这是否是唯一/最佳/最 Python 化的方法。它看起来很尴尬。实际代码:
query = 'SELECT action.descr as "action", '\n 'role.id as role_id,'\n 'role.descr as role'\n 'FROM '\n 'public.role_action_def,'\n 'public.role,'\n 'public.record_def, '\n 'public.action'\n 'WHERE role.id = role_action_def.role_id AND'\n 'record_def.id = role_action_def.def_id AND'\n 'action.id = role_action_def.action_id AND'\n 'role_action_def.account_id = ' + account_id + ' AND'\n 'record_def.account_id=' + account_id + ' AND'\n 'def_id=' + def_id
另请参阅:当整体代码行很长但不包含长字符串文字时,如何在 Python 中执行换行符(行延续)(拆分一长行源代码)?
解决方案 1:
您说的是多行字符串吗?很简单,使用三引号作为开头和结尾。
s = """ this is a very
long string if I had the
energy to type more and more ..."""
您也可以使用单引号(当然在开始和结束时有 3 个单引号),并将生成的字符串s
像任何其他字符串一样处理。
注意:与任何字符串一样,起始引号和结束引号之间的任何内容都将成为字符串的一部分,因此此示例以空格开头(如@root45 所指出的)。此字符串还将包含空格和换行符。
IE,:
' this is a very
long string if I had the
energy to type more and more ...'
最后,还可以用 Python 构造长行,如下所示:
s = ("this is a very"
"long string too"
"for sure ..."
)
其中不会包含任何多余的空格或换行符(这是一个刻意的例子,展示了跳过空格会导致什么效果):
'this is a verylong string toofor sure ...'
不需要逗号,只需将要连接的字符串放在一对括号中,并确保考虑到任何需要的空格和换行符。
解决方案 2:
如果您不想要多行字符串,而只想使用较长的单行字符串,则可以使用括号。只需确保字符串段之间不包含逗号(然后它将是一个元组)。
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)
在您正在构建的 SQL 语句中,多行字符串也可以。但如果多行字符串包含的额外空格是一个问题,那么这将是实现您想要的结果的好方法。
正如评论中所述,以这种方式连接 SQL 查询存在潜在的 SQL 注入安全风险,因此请使用数据库的参数化查询功能来防止这种情况。但是,我将保留原样,因为它直接回答了提出的问题。
解决方案 3:
对我来说,按 换行``是可行的。以下是示例:
longStr = "This is a very long string " \n "that I wrote to help somebody " \n "who had a question about " \n "writing long strings in Python"
解决方案 4:
我发现,在构建长字符串时,通常会执行类似构建 SQL 查询的操作,在这种情况下最好的做法是:
query = ' '.join(( # Note double parentheses. join() takes an iterable
"SELECT foo",
"FROM bar",
"WHERE baz",
))
Levon 的建议很好,但可能容易出现错误:
query = (
"SELECT foo"
"FROM bar"
"WHERE baz"
)
query == "SELECT fooFROM barWHERE baz" # Probably not what you want
解决方案 5:
我对这个很满意:
string = """This is a
very long string,
containing commas,
that I split up
for readability""".replace('
',' ')
解决方案 6:
该方法使用:
通过使用三重引号字符串,几乎没有内部标点符号
inspect
使用模块去除局部缩进对
account_id
和def_id
变量使用 Python 3.6 格式的字符串插值('f')。
对我来说,这种方式看起来最符合 Python 风格。
import inspect
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}'''
)
解决方案 7:
您还可以在使用“”符号时包含变量:
foo = '1234'
long_string = """fosdl a sdlfklaskdf as
as df ajsdfj asdfa sld
a sdf alsdfl alsdfl """ + foo + """ aks
asdkfkasdk fak"""
更好的方法是使用命名参数和.format():
body = """
<html>
<head>
</head>
<body>
<p>Lorem ipsum.</p>
<dl>
<dt>Asdf:</dt> <dd><a href="{link}">{name}</a></dd>
</dl>
</body>
</html>
""".format(
link='http://www.asdf.com',
name='Asdf',
)
print(body)
解决方案 8:
PEP 8 样式指南建议使用括号:
换行较长的行的首选方法是使用 Python 的隐式行续行符(在括号、中括号和大括号内)。可以将表达式放在括号内,从而将较长的行拆分为多行。应优先使用这些符号,而不是使用反斜杠进行行续行。
例子:
long_string = (
"This is a lengthy string that takes up a lot of space. I am going to "
"keep on typing words to fill up more and more space to show how you can "
"split the string across multiple lines."
)
解决方案 9:
在 Python >= 3.6 中,你可以使用格式化的字符串文字(f 字符串)
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}'''
解决方案 10:
我发现textwrap.dedent
最适合长字符串的方法如下:
def create_snippet():
code_snippet = textwrap.dedent("""\n int main(int argc, char* argv[]) {
return 0;
}
""")
do_something(code_snippet)
解决方案 11:
例如:
sql = ("select field1, field2, field3, field4 "
"from table "
"where condition1={} "
"and condition2={}").format(1, 2)
Output: 'select field1, field2, field3, field4 from table
where condition1=1 and condition2=2'
如果条件的值应该是一个字符串,您可以这样做:
sql = ("select field1, field2, field3, field4 "
"from table "
"where condition1='{0}' "
"and condition2='{1}'").format('2016-10-12', '2017-10-12')
Output: "select field1, field2, field3, field4 from table where
condition1='2016-10-12' and condition2='2017-10-12'"
解决方案 12:
其他人已经提到了括号方法,但我想补充一点,使用括号可以进行内联注释。
对每个片段进行评论:
nursery_rhyme = (
'Mary had a little lamb,' # Comments are great!
'its fleece was white as snow.'
'And everywhere that Mary went,'
'her sheep would surely go.' # What a pesky sheep.
)
继续后不允许评论:
使用反斜杠行延续符 ( `) 时,不允许注释。您将收到
SyntaxError: unexpected character after line continuation character`错误。
nursery_rhyme = 'Mary had a little lamb,' # These comments
'its fleece was white as snow.' # are invalid!
'And everywhere that Mary went,' \n 'her sheep would surely go.'
# => SyntaxError: unexpected character after line continuation character
正则表达式字符串的更好注释:
根据https://docs.python.org/3/library/re.html#re.VERBOSE中的示例,
a = re.compile(
r'd+' # the integral part
r'.' # the decimal point
r'd*' # some fractional digits
)
# Using VERBOSE flag, IDE usually can't syntax highight the string comment.
a = re.compile(r"""d + # the integral part
. # the decimal point
d * # some fractional digits""", re.X)
解决方案 13:
作为 Python 中处理长字符串的一般方法,可以使用三重引号,split
并且join
:
_str = ' '.join('''Lorem ipsum dolor sit amet, consectetur adipiscing
elit, sed do eiusmod tempor incididunt ut labore et dolore
magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation
ullamco laboris nisi ut aliquip ex ea commodo.'''.split())
输出:
'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo.'
关于 OP 提出的 SQL 查询问题,下面的答案忽略了这种构建 SQL 查询的方法的正确性,只关注以可读且美观的方式构建长字符串,而无需额外导入。它还忽略了这需要的计算负载。
使用三重引号,我们构建了一个长而可读的字符串,然后使用 将其分解为一个列表,split()
从而去除空格,然后使用 将其重新连接在一起' '.join()
。最后,我们使用以下命令插入变量format()
:
account_id = 123
def_id = 321
_str = '''
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 = {}
'''
query = ' '.join(_str.split()).format(account_id, account_id, def_id)
生成:
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 = 123 AND record_def.account_id=123 AND def_id=321
这种方法不符合PEP 8,但我发现它有时很有用。
请注意,原始字符串中的花括号是由 format() 函数使用的。
解决方案 14:
补充@Levon 的回答....
1. 创建一个像这样的多行字符串:
paragraph = """this is a very
long string if I had the
energy to type more and more ..."""
print(paragraph)
输出:
'this is a very
long string if I had the
energy to type more and more ...'
此字符串将包含换行符和空格。因此请将其删除。
2. 使用正则表达式删除多余的空格
paragraph = re.sub('s+', ' ', paragraph)
print(paragraph)
输出:
'this is a very long string if I had the energy to type more and more ...'
解决方案 15:
我个人认为以下是在 Python 中编写原始 SQL 查询的最佳(简单、安全且 Pythonic)方法,尤其是在使用Python 的 sqlite3 模块时:
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) # a tuple of query variables
cursor.execute(query, vars) # using Python's sqlite3 module
优点
简洁的代码(Pythonic!)
防止 SQL 注入
兼容 Python 2 和 Python 3(毕竟它是 Pythonic)
无需字符串连接
无需确保每行最右边的字符是空格
缺点
由于查询中的变量被
?
占位符替换,因此当查询中有很多变量时,可能很难跟踪哪个?
Python 变量将被哪个变量替换。
解决方案 16:
tl;dr:使用"""
和"""
包装字符串,如下所示
string = """\nThis is a long string
spanning multiple lines.
"""
来自Python 官方文档:
字符串文字可以跨越多行。一种方法是使用三引号:“”“...”“”或'''...'''。行尾会自动包含在字符串中,但可以通过在行尾添加 \ 来防止这种情况。以下示例:
print("""\nUsage: thingy [OPTIONS]
-h Display this usage message
-H hostname Hostname to connect to
""")
产生以下输出(请注意,不包括初始换行符):
Usage: thingy [OPTIONS]
-h Display this usage message
-H hostname Hostname to connect to
解决方案 17:
我通常使用这样的东西:
text = '''
This string was typed to be a demo
on how could we write a multi-line
text in Python.
'''
如果您想删除每行中令人讨厌的空格,您可以执行以下操作:
text = '
'.join(line.lstrip() for line in text.splitlines())
解决方案 18:
嗯。
我知道这个问题已经很久没有发布了。但我刚刚找到了我想要使用的样式,用于将长而多行的字符串分配给项目中的变量。这需要一点额外的运行时间,但仍然保留了代码的美感,即使我分配字符串的变量缩进严重。
# Suppose the following code is heavily indented
line3header = "Third"
variable = fr"""
First line.
Second line.
{line3header} line.
{{}} line.
...
The last line.
""".strip()
"""A variable whose name is Variable.
You can even add a docstring here.
"""
variable = variable.format("Fourth")
print(variable)
variable += "
"
print(variable, end="")
就是这样。
解决方案 19:
您的实际代码不应该工作;您在“行”末尾缺少空格(例如,role.descr as roleFROM...
)。
多行字符串有三重引号:
string = """line
line2
line3"""
它将包含换行符和多余的空格,但对于 SQL 来说这不是问题。
解决方案 20:
尝试这样做。像这种格式,它会返回一条连续的行,就像您已成功查询此属性一样:
"message": f'You have successfully inquired about '
f'{enquiring_property.title} Property owned by '
f'{enquiring_property.client}'
解决方案 21:
结合以下想法:
Levon或Jesse , Faheel和ddrscott
根据我的格式建议,您可以将查询写为:
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
)
vars = (account_id, account_id, def_id) # A tuple of the query variables
cursor.execute(query, vars) # Using Python's sqlite3 module
或者像:
vars = []
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 = '
vars.append(account_id) or '?'
' AND'
' record_def.account_id = '
vars.append(account_id) or '?'
' AND'
' def_id = '
vars.append(def_id) or '?'
)
cursor.execute(query, tuple(vars)) # Using Python's sqlite3 module
这与 'IN' 和 'vars.extend(options) or n_options(len(options))' 一起很有趣,其中:
def n_options(count):
return '(' + ','.join(count*'?') + ')'
或者根据darkfeline的提示,您可能仍然会在前导空格和分隔符以及命名占位符方面犯错误:
SPACE_SEP = ' '
COMMA_SEP = ', '
AND_SEP = ' AND '
query = SPACE_SEP.join((
'SELECT',
COMMA_SEP.join((
'action.descr as "action"',
'role.id as role_id',
'role.descr as role',
)),
'FROM',
COMMA_SEP.join((
'public.role_action_def',
'public.role',
'public.record_def',
'public.action',
)),
'WHERE',
AND_SEP.join((
'role.id = role_action_def.role_id',
'record_def.id = role_action_def.def_id',
'action.id = role_action_def.action_id',
'role_action_def.account_id = :account_id',
'record_def.account_id = :account_id',
'def_id = :def_id',
)),
))
vars = {'account_id':account_id,'def_id':def_id} # A dictionary of the query variables
cursor.execute(query, vars) # Using Python's sqlite3 module
参见Cursor.execute-function 的文档。
“这是[最 Pythonic 的] 方式!” - ......
解决方案 22:
您还可以将 SQL 语句放在单独的文件中,action.sql
然后使用以下命令将其加载到 .py 文件中:
with open('action.sql') as f:
query = f.read()
这样 SQL 语句将与 Python 代码分离。如果 SQL 语句中有需要从 Python 中填充的参数,则可以使用字符串格式(例如 %s 或 {field})。
解决方案 23:
另一个我认为更易读的选项是,当代码(例如,变量)缩进并且输出字符串应该是单行(没有换行符)时:
def some_method():
long_string = """
A presumptuous long string
which looks a bit nicer
in a text editor when
written over multiple lines
""".strip('
').replace('
', ' ')
return long_string
解决方案 24:
“À la” Scala方式(但我认为这是最 Pythonic 的方式,正如 OP 要求的那样):
description = """
| The intention of this module is to provide a method to
| pass meta information in markdown_ header files for
| using it in jinja_ templates.
|
| Also, to provide a method to use markdown files as jinja
| templates. Maybe you prefer to see the code than
| to install it.""".replace('
|
','
').replace(' | ',' ')
如果您想要没有跳转行的最终 str,只需将其放在`
`第二个替换的第一个参数的开头:
.replace('
| ',' ')`.
注意:“...模板。”和“此外,...”之间的白线要求在 后有一个空格|
。
解决方案 25:
我知道这是一个相当老的问题,但与此同时 Python 已经发生了变化,我没有看到这个答案,所以我们开始吧。
另一种方法是使用 \ 剪切当前行并移动到另一行:
print("This line will \nget carried over to\n the new line.\nNotice how this\nword will be together because \nof no space around it")
解决方案 26:
来自Python 官方文档:
字符串文字可以跨越多行。一种方法是使用三引号:“”“...”“”或'''...'''。行尾会自动包含在字符串中,但可以通过在行尾添加 \ 来防止这种情况。以下示例:
print("""\nUsage: thingy [OPTIONS]
-h Display this usage message
-H hostname Hostname to connect to
""")
产生以下输出(请注意,不包括初始换行符):
解决方案 27:
为了在字典中定义一个长字符串,
保留换行符但省略空格,我最终在常量中定义了该字符串,如下所示:
LONG_STRING = \n"""
This is a long sting
that contains newlines.
The newlines are important.
"""
my_dict = {
'foo': 'bar',
'string': LONG_STRING
}
解决方案 28:
我使用递归函数来构建复杂的 SQL 查询。此技术通常可用于构建大型字符串,同时保持代码的可读性。
# Utility function to recursively resolve SQL statements.
# CAUTION: Use this function carefully, Pass correct SQL parameters {},
# TODO: This should never happen but check for infinite loops
def resolveSQL(sql_seed, sqlparams):
sql = sql_seed % (sqlparams)
if sql == sql_seed:
return ' '.join([x.strip() for x in sql.split()])
else:
return resolveSQL(sql, sqlparams)
PS:如果需要的话,可以看一下出色的python-sqlparse库,以便漂亮地打印 SQL 查询。
解决方案 29:
我喜欢这种方法,因为它优先考虑阅读。如果我们有长字符串,那就没办法了!取决于你所在的缩进级别,并且每行仍然限制为 80 个字符……好吧……无需多言
在我看来,Python 风格指南仍然非常模糊。我采用了Eero Aaltonen 的方法,因为它重视阅读和常识。我明白风格指南应该对我们有所帮助,而不是让我们的生活变得一团糟。
class ClassName():
def method_name():
if condition_0:
if condition_1:
if condition_2:
some_variable_0 =\n"""
some_js_func_call(
undefined,
{
'some_attr_0': 'value_0',
'some_attr_1': 'value_1',
'some_attr_2': '""" + some_variable_1 + """'
},
undefined,
undefined,
true
)
"""
解决方案 30:
import inspect
def get_single_line_string(multiline: str) -> str:
lines = [line.strip() for line in multiline.splitlines()]
return " ".join(line for line in lines if line)
In [89]: i=10; get_single_line_string(f"""
...:
...: first line
...: dfdf
...: dfdfd{i}
...: fdf
...:
...: """)
Out[89]: 'first line dfdf dfdfd10 fdf'
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 项目管理必备:盘点2024年13款好用的项目管理软件