python - separate - variable multiline




Maneira Pythonic para criar uma longa seqüência de multi-linha (13)

Eu tenho uma consulta muito longa. Eu gostaria de dividi-lo em várias linhas em Python. Uma maneira de fazer isso em JavaScript seria usar várias frases e juntá-las com um operador + (eu sei, talvez não seja a maneira mais eficiente de fazer isso, mas não estou realmente preocupado com o desempenho nesse estágio, apenas a legibilidade do código ). Exemplo:

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

Eu tentei fazer algo semelhante em Python, mas não funcionou, então usei \ para dividir a longa string. No entanto, eu não tenho certeza se esta é a única maneira / melhor / pythonicest de fazê-lo. Parece estranho. Código real:

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

"À la" Scala way (mas eu acho que é a maneira mais pythonic como exige 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('            | ',' ')

Se você quiser str final sem linhas de salto, basta colocar \n no início do primeiro argumento da segunda substituição:

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

Nota: a linha branca entre "... modelos". e "Além disso, ..." requer um espaço em branco após o | .


Acho textwrap.dedent o melhor para longas seqüências de caracteres, conforme descrito here :

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

Essa abordagem usa apenas uma barra invertida para evitar um avanço de linha inicial, quase nenhuma pontuação interna usando uma string tripla entre aspas, elimina o recuo local usando o módulo textwrap e também usa a interpolação de string formatada em python 3.6 ('f') para o account_id e def_id variáveis. Desta forma, parece o mais pythonic para mim.

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

Eu acho que ao construir strings longas, você geralmente está fazendo algo como construir uma consulta SQL, caso em que isso é melhor:

query = ' '.join((  # note double parens, join() takes an iterable
    "SELECT foo",
    "FROM bar",
    "WHERE baz",
))

O que Levon sugeriu é bom, mas pode ser vulnerável a erros:

query = (
    "SELECT foo"
    "FROM bar"
    "WHERE baz"
)

query == "SELECT fooFROM barWHERE baz"  # probably not what you want

Eu gosto dessa abordagem porque privilegia a leitura. Nos casos em que temos longas cordas, não há como! Dependendo do nível de recuo que você está e ainda limitado a 80 caracteres por linha ... Bem ... Não precisa dizer mais nada. Na minha opinião, os guias de estilo python ainda são muito vagos. Tomei a abordagem do @Eero Aaltonen porque privilegia a leitura e o bom senso. Eu entendo que os guias de estilo devem nos ajudar e não tornar nossas vidas uma bagunça. Obrigado!

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

Eu me achei feliz com este:

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

Eu uso uma função recursiva para construir consultas SQL complexas. Essa técnica geralmente pode ser usada para criar grandes seqüências de caracteres, mantendo a legibilidade do código.

# 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: Dê uma olhada na fantástica biblioteca python-sqlparse para imprimir consultas SQL, se necessário. http://sqlparse.readthedocs.org/en/latest/api/#sqlparse.format


Geralmente, eu uso list e join para comentários / strings de várias linhas.

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)

você pode usar qualquer string para unir todos os elementos da lista como ' \n ' (nova linha) ou ' , ' (vírgula) ou ' '(espaço)

Felicidades..!!


Por exemplo:

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'

Se o valor da condição deve ser uma string, você pode fazer assim:

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

Quebrando linhas por \ works para mim. Aqui está um exemplo:

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

Seu código atual não deve funcionar, você está perdendo espaços em branco no final de "linhas" (por exemplo: role.descr as roleFROM... )

Há triplequotes para string de múltiplas linhas:

string = """line
  line2
  line3"""

Ele conterá as quebras de linha e espaços extras, mas para SQL não é um problema.


Você está falando sobre seqüências de várias linhas? Fácil, use aspas triplas para começar e terminar.

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

Você pode usar aspas simples também (3 delas, é claro, no início e no fim) e tratar as cadeias de caracteres resultantes como qualquer outra string.

NOTA : Assim como com qualquer string, qualquer coisa entre aspas inicial e final torna-se parte da string, então este exemplo tem um espaço em branco à esquerda (como apontado por @ root45). Esta string também conterá espaços em branco e novas linhas.

Ou seja:

' this is a very\n        long string if I had the\n        energy to type more and more ...'

Finalmente, também é possível construir linhas longas em Python assim:

 s = ("this is a very"
      "long string too"
      "for sure ..."
     )

que não incluirá espaços em branco extras ou novas linhas (este é um exemplo deliberado que mostra como o efeito de pular espaços em branco resultará):

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

Sem vírgulas necessárias, simplesmente coloque as strings a serem unidas em um par de parênteses e certifique-se de considerar quaisquer espaços em branco e novas linhas necessários.


Você também pode concatenar variáveis ​​ao usar a notação "":

foo = '1234'

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

EDIT: Encontrado um caminho melhor, com params nomeados e .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)




multilinestring