如何将长字符串的定义拆分为多行?

我有一个很长的查询。我想在Python中将它分成几行。在JavaScript中这样做的一种方法是使用几个句子并将它们与+运算符连接起来(我知道,也许这不是最有效的方法,但我并不真正关心现阶段的性能,只是代码易读性)。示例:

var long_string = 'some text not important. just garbage to' +'illustrate my example';

我尝试在Python中做类似的事情,但不起作用,所以我使用\拆分长字符串。但是,我不确定这是否是唯一/最好/pythonicest的方式。看起来很尴尬。实际代码:

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
1749198 次浏览

你是在说多行字符串吗?简单,使用三重引号来开始和结束它们。

s = """ this is a verylong string if I had theenergy to type more and more ..."""

您也可以使用单引号(其中3个在开始和结束时)并将结果字符串s视为任何其他字符串。

:就像任何字符串一样,起始引号和结束引号之间的任何内容都将成为字符串的一部分,因此此示例有一个前导空白(如@root45所指出的)。此字符串还将包含空白和换行符。

即:

' this is a very\n        long string if I had the\n        energy to type more and more ...'

最后,还可以在Python中构造长行,如下所示:

 s = ("this is a very""long string too""for sure ...")

这将没有包括任何额外的空白或换行符(这是一个故意的例子,显示跳过空白会导致什么效果):

'this is a verylong string toofor sure ...'

不需要逗号,只需将要连接在一起的字符串放入一对括号中,并确保考虑任何需要的空格和换行符。

您的实际代码不应该工作;您在“行”末尾缺少空格(例如,role.descr as roleFROM...)。

多行字符串有三重引号:

string = """lineline2line3"""

它将包含换行符和额外的空格,但对于SQL这不是问题。

如果您不想要多行字符串,而只想要一个长的单行字符串,您可以使用括号。只需确保字符串段之间不包含逗号(那么它将是一个元组)。

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注入安全风险,因此请使用数据库的参数化查询功能来防止这种情况。但是,我将保留答案,因为它直接回答了所问的问题。

您还可以将SQL语句放在单独的文件action.sql中,并将其加载到. py文件中:

with open('action.sql') as f:query = f.read()

因此,SQL语句将与Python代码分开。如果SQL语句中有需要从Python填充的参数,您可以使用字符串格式(如%s或{field})。

我发现自己对这个很满意:

string = """This is avery long string,containing commas,that I split upfor readability""".replace('\n',' ')

我发现在构建长字符串时,你通常会做一些类似于构建SQL查询的事情,在这种情况下最好:

query = ' '.join((  # Note double parentheses. join() takes an iterable"SELECT foo","FROM bar","WHERE baz",))

什么莱文建议是好的,但它可能容易出错:

query = ("SELECT foo""FROM bar""WHERE baz")
query == "SELECT fooFROM barWHERE baz"  # Probably not what you want

\断线对我很有效。这是一个例子:

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

我使用递归函数来构建复杂的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 loopsdef 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)

附注:看看真棒python-sqlparse库漂亮打印SQL查询,如果需要的话。

您还可以在使用“”符号时包含变量:

foo = '1234'
long_string = """fosdl a sdlfklaskdf asas df ajsdfj asdfa slda sdf alsdfl alsdfl """ +  foo + """ aksasdkfkasdk fak"""

更好的方法是,使用命名参数和. form():

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)

例如:

sql = ("select field1, field2, field3, field4 ""from table ""where condition1={} ""and condition2={}").format(1, 2)
Output: 'select field1, field2, field3, field4 from tablewhere 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 wherecondition1='2016-10-12' and condition2='2017-10-12'"

当代码(例如变量)缩进并且输出字符串应该是单行(没有换行符)时,我认为另一个选项更具可读性:

def some_method():
long_string = """A presumptuous long stringwhich looks a bit nicerin a text editor whenwritten over multiple lines""".strip('\n').replace('\n', ' ')
return long_string

scala方式(但我认为这是OP要求的最Pythonic的方式):

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('\n            | \n','\n').replace('            | ',' ')

如果你想要没有跳转行的最终str,只需将\n放在第二个替换的第一个参数的开头:

.replace('\n            | ',' ')`.

注意:“……模板”和“此外,……”之间的白线需要在|之后有一个空格。

在Python>=3.6中,您可以使用格式化字符串文字(f字符串)

query= f'''SELECT   action.descr as "action"role.id as role_id,role.descr as roleFROMpublic.role_action_def,public.role,public.record_def,public.actionWHERE role.id = role_action_def.role_id ANDrecord_def.id = role_action_def.def_id ANDaction.id = role_action_def.action_id ANDrole_action_def.account_id = {account_id} ANDrecord_def.account_id = {account_id} ANDdef_id = {def_id}'''

我喜欢这种方法,因为它赋予阅读特权。在我们有长字符串的情况下,没有办法!根据您所处的缩进级别,每行仍然限制为80个字符…嗯…没必要再说什么了

在我看来,Python风格指南仍然非常模糊。我选择了Eero Aaltonen方法,因为它优先阅读和常识。我明白风格指南应该帮助我们,而不是让我们的生活一团糟。

class ClassName():def method_name():if condition_0:if condition_1:if condition_2:some_variable_0 =\"""some_js_func_call(undefined,{'some_attr_0': 'value_0','some_attr_1': 'value_1','some_attr_2': '""" + some_variable_1 + """'},undefined,undefined,true)"""

我个人认为以下是在Python中编写原始SQL查询的最佳(简单,安全和Pythonic)方法,特别是在使用Python的sqlite3模块时:

query = '''SELECTaction.descr as action,role.id as role_id,role.descr as roleFROMpublic.role_action_def,public.role,public.record_def,public.actionWHERErole.id = role_action_def.role_idAND record_def.id = role_action_def.def_idAND action.id = role_action_def.action_idAND role_action_def.account_id = ?AND record_def.account_id = ?AND def_id = ?'''vars = (account_id, account_id, def_id)   # a tuple of query variablescursor.execute(query, vars)   # using Python's sqlite3 module

优点

  • 整洁简单的代码(Pythonic!)
  • 安全SQL注射
  • 兼容Python 2和Python 3(毕竟是Pythonic)
  • 不需要字符串连接
  • 无需确保每行最右边的字符是空格

缺点

  • 由于查询中的变量被?占位符替换,当查询中有很多变量时,跟踪哪个?将被哪个Python变量替换可能会变得有点困难。

这种方法使用:

  • 使用三重引号字符串几乎没有内部标点符号
  • 使用inspect模块去除本地缩进
  • account_iddef_id变量使用Python 3.6格式的字符串插值('f')。

这种方式看起来最Pythonic给我。

import inspect
query = inspect.cleandoc(f'''SELECT action.descr as "action",role.id as role_id,role.descr as roleFROMpublic.role_action_def,public.role,public.record_def,public.actionWHERE role.id = role_action_def.role_id ANDrecord_def.id = role_action_def.def_id ANDaction.id = role_action_def.action_id ANDrole_action_def.account_id = {account_id} ANDrecord_def.account_id={account_id} ANDdef_id={def_id}''')

我通常使用这样的东西:

text = '''This string was typed to be a demoon how could we write a multi-linetext in Python.'''

如果您想删除每行中烦人的空格,您可以执行以下操作:

text = '\n'.join(line.lstrip() for line in text.splitlines())

我发现#0最适合长字符串,如这里所述:

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

通常,我使用listjoin作为多行注释/字符串。

lines = list()lines.append('SELECT action.enter code here descr as "action", ')lines.append('role.id as role_id,')lines.append('role.descr as role')lines.append('FROM ')lines.append('public.role_action_def,')lines.append('public.role,')lines.append('public.record_def, ')lines.append('public.action')query = " ".join(lines)

您可以使用任何字符串来连接所有这些列表元素,例如'\n'(换行符)或','(逗号)或' '(空格)。

其他人已经提到了括号方法,但我想补充一点,使用括号,允许内联注释。

评论每个片段:

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,'      \'her sheep would surely go.'# => SyntaxError: unexpected character after line continuation character

Regex字符串的更好注释:

https://docs.python.org/3/library/re.html#re.VERBOSE为例,

a = re.compile(r'\d+'  # the integral partr'\.'   # the decimal pointr'\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)

试试这样的东西。就像这种格式一样,它会返回一条连续的线,就像你已经成功查询了这个属性一样:

"message": f'You have successfully inquired about 'f'{enquiring_property.title} Property owned by 'f'{enquiring_property.client}'

tl; dr:使用#0和#1包装字符串,如

string = """\This is a long stringspanning multiple lines."""

官方Python留档

字符串文字可以跨越多行。一种方法是使用三重引号:“””…“”或“”…“'。行尾自动包含在字符串中,但可以通过添加\在行尾。以下示例:

print("""\Usage: 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

官方Python留档

字符串文字可以跨越多行。一种方法是使用三重引号:“””…“”或“”…“'。行尾自动包含在字符串中,但可以通过添加\在行尾。以下示例:

print("""\Usage: thingy [OPTIONS]-h                        Display this usage message-H hostname               Hostname to connect to""")

产生以下输出(注意初始换行符不是包括):

为了在一个字典中定义一个长字符串,保留换行符但省略空格,我最终在一个常量中定义了字符串,如下所示:

LONG_STRING = \"""This is a long stingthat contains newlines.The newlines are important."""
my_dict = {'foo': 'bar','string': LONG_STRING}

作为Python中长字符串的一般方法,您可以使用三重引号,splitjoin

_str = ' '.join('''Lorem ipsum dolor sit amet, consectetur adipiscingelit, sed do eiusmod tempor incididunt ut labore et doloremagna aliqua. Ut enim ad minim veniam, quis nostrud exercitationullamco 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 = 123def_id = 321
_str = '''SELECT action.descr AS "action", role.id AS role_id, role.descr AS roleFROM public.role_action_def, public.role, public.record_def, public.actionWHERE role.id = role_action_def.role_idAND record_def.id = role_action_def.def_idAND' action.id = role_action_def.action_idAND 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,但我发现它有时很有用。

请注意,原始字符串中的花括号由form()函数使用。

结合以下思想:

Levon杰西Faheelddrscott

根据我的格式建议,您可以将查询编写为:

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 variablescursor.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(选项)或n_options(len(选项))'一起有趣,其中:

def n_options(count):return '(' + ','.join(count*'?') + ')'

或者使用来自暗猫的提示,您可能仍然会在那些前导空格和分隔符以及命名占位符上犯错误:

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 variablescursor.execute(query, vars)                       # Using Python's sqlite3 module

留档Cursor.execute功能

“这是[最Pythonic]的方式!”-…

添加到@Levon的回答……

1.创建一个多行字符串,如下所示:

paragraph = """this is a verylong string if I had theenergy to type more and more ..."""
print(paragraph)

输出:

'this is a very\n        long string if I had the\n        energy to type more and more ...'

这个字符串将有换行符和空格。所以删除它们。

2.使用regex删除多余的空格

paragraph = re.sub('\s+', ' ', paragraph)print(paragraph)

输出:

'this is a very long string if I had the energy to type more and more ...'

我知道这是一个相当古老的问题,但Python在此期间发生了变化,我看不到这个答案,所以我们开始吧。

另一种方法是使用\剪切当前行并移动到另一行:

print("This line will \get carried over to\the new line.\Notice how this\word will be together because \of no space around it")

嗯。

我知道这个问题已经发布很长时间了。但我刚刚找到了我想用来将长字符串和多行字符串分配给项目中的变量的样式。这需要一些额外的运行时间,但仍然保留了代码的美丽,即使我将字符串分配给的变量严重缩进。

    # Suppose the following code is heavily indentedline3header = "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 += "\n"print(variable, end="")

这就对了。

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.")