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

解决方案

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

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

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

其他提示

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

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

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

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

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

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

我发现在构建长字符串时,您通常会执行诸如构建 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

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

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)

该方法使用:

  • 只需一个反斜杠即可避免初始换行
  • 使用三重引号字符串几乎没有内部标点符号
  • 使用去除局部缩进 文本换行 inspect 模块
  • 使用 python 3.6 格式的字符串插值 ('f') account_iddef_id 变量。

这种方式对我来说看起来最Pythonic。

# 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

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

例如:

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

我个人认为以下是在 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 变量时,将被替换为哪个 Python 变量。

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

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

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

对每个片段进行评论:

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)

我通常使用这样的东西:

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

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

多行字符串有三引号:

string = """line
  line2
  line3"""

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

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

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

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

“啦啦” 斯卡拉 方式(但我认为这是 OQ 要求的最 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            | ',' ')`.

笔记:“ ...模板”之间的白线。和“另外……”需要一个空格之后 |.

长话短说:使用 """\""" 包裹字符串, ,如

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

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

Usage: thingy [OPTIONS]
     -h                        Display this usage message
     -H hostname               Hostname to connect to

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

附:如果需要的话,看看很棒的 python-sqlparse 库来漂亮地打印 SQL 查询。http://sqlparse.readthedocs.org/en/latest/api/#sqlparse.format

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

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 

嘿,尝试这样的事情,希望它能起作用,就像这种格式一样,它会返回一条连续的行,就像您已成功查询此属性一样

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

我喜欢这种方法,因为它有利于阅读。如果我们有很长的字符串,那就没有办法了!根据您所处的缩进级别,每行仍限制为 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文档:

字符串文字可以跨越多行。一种方法是使用三重报价:“““...“““ 或者 '''...'''。线的末端自动包含在字符串中,但是可以通过在行末端添加来防止这种情况。下面的例子:

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

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

一般来说,我使用 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'(换行符)或 ','(逗号)或 ''(空间)

干杯..!!

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top