Pythonic方式创建一个长多行字符串

时间:2012-05-18 22:21:10

标签: python string multiline multilinestring

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

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

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

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

26 个答案:

答案 0 :(得分:1755)

你在谈论多线字符串吗?简单,使用三重引号开始和结束它们。

s = """ this is a very
        long string if I had the
        energy 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 ...'

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

答案 1 :(得分:152)

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

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语句中,多行字符串也可以。但是如果多行字符串包含的额外空格会有问题,那么这将是实现所需内容的好方法。

答案 2 :(得分:117)

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

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

答案 3 :(得分:41)

我发现自己对这个感到满意:

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

答案 4 :(得分:34)

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

query = ' '.join((  # note double parens, 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 :(得分:25)

使用“”“表示法时,您也可以连接变量:

foo = '1234'

long_string = """fosdl a sdlfklaskdf as
as df ajsdfj asdfa sld
a sdf alsdfl alsdfl """ +  foo + """ aks
asdkfkasdk fak"""

编辑:找到一种更好的方法,使用命名的params和.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)

答案 6 :(得分:19)

在Python&gt; = 3.6中,您可以使用Formatted string literals (f string)

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}'''

答案 7 :(得分:14)

此方法使用:

  • 只需一次反斜杠即可避免初始换行
  • 使用三重引号字符串
  • 几乎没有内部标点符号
  • 使用 textwrap inspect模块删除本地缩进
  • account_iddef_id变量使用python 3.6格式化字符串插值(&#39; f&#39;)。

这种方式看起来对我来说是最诡异的。

# import textwrap  # See update to answer below
import inspect

# query = textwrap.dedent(f'''\
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/29/2019合并@ ShadowRanger的建议,使用inspect.cleandoc代替textwrap.dedent

答案 8 :(得分:8)

我发现textwrap.dedent最适合长字符串,如here所述:

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

答案 9 :(得分:7)

我个人认为以下是在Python中编写原始SQL查询的最佳(简单,安全和Pythonic)方式,尤其是在使用Python's sqlite3 module时:

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变量替换可能会变得有点困难。查询。

答案 10 :(得分:6)

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

_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

编辑:这种方法与PEP8不符,但我有时发现它很有用

答案 11 :(得分:4)

我通常使用这样的东西:

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())

答案 12 :(得分:3)

结合以下方面的想法:

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

请参见documentation of Cursor.execute-function

“这是[最pythonic]的方式!” -...

答案 13 :(得分:3)

您的实际代码不起作用,您在“行”末尾缺少空格(例如:role.descr as roleFROM...

多行字符串有三重引号:

string = """line
  line2
  line3"""

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

答案 14 :(得分:2)

“Àla” Scala 方式(但我认为是OQ要求的最蟒蛇方式):

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('            | ',' ')

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

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

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

答案 15 :(得分:2)

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

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

来自official python documentation

  

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

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

答案 16 :(得分:2)

您还可以将sql语句放在单独的文件action.sql中,并使用

将其加载到py文件中
with open('action.sql') as f:
   query = f.read()

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

答案 17 :(得分:1)

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

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 

答案 18 :(得分: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)

P.S:看看真棒的python-sqlparse库,如果需要,可以打印SQL查询。 http://sqlparse.readthedocs.org/en/latest/api/#sqlparse.format

答案 19 :(得分:1)

使用三引号。人们经常在程序开始时使用它们来创建文档字符串,以解释其目的以及与该文档创建相关的其他信息。人们还在功能中使用这些来解释功能的目的和应用。示例:

'''
Filename: practice.py
File creator: me
File purpose: explain triple quotes
'''


def example():
    """This prints a string that occupies multiple lines!!"""
    print("""
    This
    is 
    a multi-line
    string!
    """)

答案 20 :(得分:0)

我喜欢这种方法,因为它特权阅读。在我们有长串的情况下,没有办法!根据您所在的缩进程度而定,每行仍然限制为80个字符......好吧......不需要再说什么了。在我看来,蟒蛇风格指南仍然非常模糊。我采用了@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
)
"""

答案 21 :(得分:0)

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

评论每个片段:

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)

答案 22 :(得分:0)

尝试这种希望能起作用的方法,就像这种格式,它将返回一条连续的行,就像您已成功查询该属性一样。

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

答案 23 :(得分:0)

来自official python documentation

  

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

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

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

答案 24 :(得分:0)

要在字典中定义一个长字符串, 保留换行符,但省略空格,我最终在这样的常量中定义了字符串:

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

my_dict = {
   'foo': 'bar',
   'string': LONG_STRING
}

答案 25 :(得分:-3)

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

干杯.. !!