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

2024-11-27 10:43:00
admin
原创
17
摘要:问题描述:我有一个很长的查询。我想在 Python 中将其拆分成几行。在 JavaScript 中执行此操作的一种方法是使用几个句子并用+运算符将​​它们连接起来(我知道,这可能不是最有效的方法,但在这个阶段我并不真正关心性能,只是关心代码的可读性)。示例:var long_string = 'some te...

问题描述:

我有一个很长的查询。我想在 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_iddef_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'
相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   657  
  如何借鉴华为IPD体系优化企业研发?在当今竞争激烈的市场环境中,企业要想保持技术领先和产品竞争力,必须拥有一套高效且严谨的研发管理体系。华为作为全球领先的ICT解决方案提供商,其集成产品开发(IPD, Integrated Product Development)体系与质量管理体系(如ISO 9000系列)的融合实践,...
IPD项目管理   15  
  IPD流程图的7种经典绘制方法详解在产品开发领域,集成产品开发(Integrated Product Development,简称IPD)流程被广泛应用,以提高产品开发的效率和质量。IPD流程图作为这一流程的可视化工具,其绘制方法至关重要。本文将详细介绍七种经典的IPD流程图绘制方法,帮助项目管理人员和团队更好地理解和...
IPD研发管理体系   18  
  IPD流程:企业创新管理的核心引擎在当今快速变化的市场环境中,企业要想持续保持竞争力,就必须不断进行创新。而IPD(Integrated Product Development,集成产品开发)流程作为一种先进的产品开发管理模式,正逐渐成为众多企业提升创新能力、加速产品上市速度、降低开发成本的重要选择。本文将深入探讨IP...
IPD管理   18  
  IPD流程与传统产品开发流程的概述在产品开发领域,企业不断寻求高效、系统的管理方法以确保产品能够顺利从概念转化为市场成功的产品。集成产品开发(Integrated Product Development,简称IPD)流程与传统产品开发流程是两种截然不同的管理理念和方法。传统产品开发流程往往以职能部门为核心,各部门按顺序...
IPD流程中PDCP是什么意思   16  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用