首页 文章

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

提问于
浏览
873

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

19 回答

  • 1

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

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

    我喜欢这种方法,因为它特权阅读 . 在我们有长串的情况下,没有办法!根据您所在的缩进程度而定,每行仍然限制为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
    )
    """
    
  • 36

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

    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
    
  • 1505

    这种方法只使用一个反斜杠来避免初始换行,通过使用三引号字符串几乎没有内部标点符号,使用textwrap模块剥离局部缩进,并且还使用python 3.6格式化字符串插值('f')用于 account_iddef_id 变量 . 这种方式看起来对我来说是最诡异的 .

    import textwrap
    
    query = textwrap.dedent(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}'''
    )
    
  • 106

    您还可以在使用“”符号时连接变量:

    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)
    
  • 134

    "À la" Scala方式(但我认为是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('            | ',' ')
    

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

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

    注意:"...templates."和_75650之间的白线在 | 之后需要一个空格 .

  • 8

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

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

    所以sql语句将与python代码分开 . 如果sql语句中有需要从python填充的参数,可以使用字符串格式化(如%s或

  • 6

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

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

    • Safe from SQL injection

    • 兼容Python 2和Python 3(毕竟它是Pythonic)

    • 不需要字符串连接

    • 无需确保每行的最右侧字符是空格

    缺点

    • 由于查询中的变量被 ? 占位符替换,因此当查询中存在大量变量时,跟踪哪个 ? 被哪个Python变量替换可能会变得有点困难 .
  • 17

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

  • 22

    我发现在构建长字符串时,通常会执行类似构建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
    
  • 0

    例如:

    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'
    

    如果condition的值应该是一个字符串,你可以这样做:

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

    我经常使用这样的东西:

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

    通常,我使用 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 '(newline) or ' , '(comma) or ' `` '(空格)

    干杯..!!

  • 0

    在Python> = 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}'''
    
  • 28

    我发现textwrap.dedent对于长字符串是最好的here

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

    你在谈论多线字符串吗?轻松,使用三重引号来开始和结束它们 .

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

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

    NOTE :与任何字符串一样,起始引号和结束引号之间的任何内容都成为字符串的一部分,因此该示例有一个前导空格(由@ 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 ..."
         )
    

    这将是 not 包括任何额外的空格或换行符(这是一个故意的例子,显示跳过空格的效果会产生什么):

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

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

  • 3

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

    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

    \ 的突破线对我有用 . 这是一个例子:

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

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

    多行字符串有三重引号:

    string = """line
      line2
      line3"""
    

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

相关问题