1704

我有一个很长的查询。我想在 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
4

30 回答 30

2850

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

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\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 ...'

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

于 2012-05-18T22:22:54.710 回答
260

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

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

于 2012-05-18T22:26:35.373 回答
170

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

longStr = "This is a very long string " \
        "that I wrote to help somebody " \
        "who had a question about " \
        "writing long strings in Python"
于 2014-06-20T16:16:55.663 回答
59

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

string = """This is a
very long string,
containing commas,
that I split up
for readability""".replace('\n',' ')
于 2013-01-04T10:39:29.597 回答
57

我发现在构建长字符串时,您通常会执行构建 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
于 2014-06-19T07:06:24.120 回答
48

这种方法使用:

  • 使用三引号字符串几乎没有内部标点符号
  • inspect使用模块去除局部缩进
  • account_id对和def_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 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}'''
)
于 2018-06-07T16:58:29.713 回答
41

您还可以在使用 """ 表示法时包含变量:

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)
于 2015-10-06T22:33:07.997 回答
29

在 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}'''
于 2017-04-25T18:47:47.443 回答
22

例如:

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'"
于 2016-05-12T12:05:08.100 回答
20

我发现这里textwrap.dedent描述的最适合长字符串:

def create_snippet():
    code_snippet = textwrap.dedent("""\
        int main(int argc, char* argv[]) {
            return 0;
        }
    """)
    do_something(code_snippet)
于 2018-07-05T06:55:59.737 回答
18

其他人已经提到了括号方法,但我想用括号添加它,允许内联注释。

评论每个片段:

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

对正则表达式字符串的更好评论:

基于来自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)
于 2019-05-06T23:13:44.613 回答
15

作为在 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() 函数使用。

于 2020-04-08T14:41:49.880 回答
14

我个人认为以下是在 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 变量将被哪个变量替换可能会变得有点困难。
于 2017-11-14T19:16:44.270 回答
11

tl;dr:使用"""\and"""来包装字符串,如

string = """\
This is a long string
spanning 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
于 2019-08-12T16:05:49.720 回答
10

添加到@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\n        long string if I had the\n        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 ...'
于 2021-10-12T07:44:01.633 回答
6

我通常使用这样的东西:

text = '''
    This string was typed to be a demo
    on how could we write a multi-line
    text in Python.
'''

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

text = '\n'.join(line.lstrip() for line in text.splitlines())
于 2018-06-21T17:36:05.487 回答
5

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

多行字符串有三引号:

string = """line
  line2
  line3"""

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

于 2012-05-18T22:25:30.547 回答
5

嗯。

I know it's been a long time since this question got posted. But I just found the style I would like to use to assign long and multiline strings to variables in my projects. This takes a bit of extra runtime, but still preserves the beauty of the code, even if the variable I am assigning my string to is heavily indented.

    # Suppose the following code is heavily indented
    line3header = "Third"
    variable = fr"""

First line.
Second line.
{line3header} line.
{{}} line.
...
The last line.

    """
    variable = variable.strip()
    variable = variable.format("Fourth")
    variable += "\n"

There it goes.

于 2022-01-05T17:51:43.390 回答
4

尝试这样的事情。就像这种格式一样,它会返回一条连续的线,就像您已成功查询此属性一样:

"message": f'You have successfully inquired about '
           f'{enquiring_property.title} Property owned by '
           f'{enquiring_property.client}'
于 2019-06-19T19:17:46.423 回答
4

结合以下想法:

LevonJesseFaheelddrscott

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

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) 或 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] 的方式!” - ...

于 2020-11-18T02:48:22.790 回答
4

我知道这是一个相当古老的问题,但与此同时 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")
于 2021-10-14T09:23:29.090 回答
3

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

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

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

于 2012-05-21T22:25:13.500 回答
3

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

def some_method():

    long_string = """
A presumptuous long string
which looks a bit nicer
in a text editor when
written over multiple lines
""".strip('\n').replace('\n', ' ')

    return long_string
于 2016-09-19T13:32:22.417 回答
3

“À la” 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            | ',' ')`.

注意:“...模板”之间的白线。并且 "Also, ..." 之后需要一个空格|

于 2017-04-12T03:00:00.600 回答
2

来自官方 Python 文档

字符串文字可以跨越多行。一种方法是使用三引号:"""...""" 或 '''...'''。行尾自动包含在字符串中,但可以通过在行尾添加 \ 来防止这种情况。下面的例子:

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

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

于 2019-08-12T16:09:05.900 回答
1

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

于 2015-04-09T00:39:22.633 回答
0

我喜欢这种方法,因为它优先阅读。在我们有长字符串的情况下,没有办法!根据您所处的缩进级别,每行仍限制为 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
)
"""
于 2017-06-01T12:58:19.057 回答
0

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

LONG_STRING = \
"""
This is a long sting
that contains newlines.
The newlines are important.
"""

my_dict = {
   'foo': 'bar',
   'string': LONG_STRING
}
于 2020-01-03T14:44:46.493 回答
-1

创建字符串

Python 字符串是通过将字符串的内容分配给写在双引号或单引号内的变量来创建的

Str1 ="Ramesh"  

Str2 ='Mahesh'

print(Str1) #Ramesh

print(Str2) #Mahesh

索引字符串

使用索引方法提取字符串(字符)的内容很有帮助,其中 python 字符串索引从索引零开始(Python 字符串索引为零)

Example of extracting string using positive string indexing :

Str1 = "Ramesh"

Str1[0] = "R"

Str1[1] = "a"

Str1[2] = "m"

Str1[3] = "e"

Str1[4] = "s"

Str1[5] = "h"

使用负字符串索引提取字符串的示例:

Str1 = "Ramesh"

Str1[-6] = "R"

Str1[-5] = "a"

Str1[-4] = "m"

Str1[-3] = "e"

Str1[-2] = "s"

Str1[-1] = "h"

print(Str1[0]) #'R'

print(Str1[0:]) #'Ramesh'

print(Str1[2:]) #'mesh'

print(Str1[:6]) #'Ramesh'

print(Str1[-1:]) #'Ramesh'

创建长多行字符串的 Pythonic 方法

"""Creating Python Comments. Python provides a single option to create a comment, using the pound sign, sometimes called the hash symbol
Python Multiline Comments with Consecutive Single-Line Comments
Python Multiline Comments with Multiline Strings
"""
于 2022-01-02T07:03:48.417 回答
-11

通常,我将listandjoin用于多行注释/字符串。

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'(换行符)或 ' ,'(逗号)或 ' '(空格)。

于 2018-09-28T10:56:50.700 回答