Pythonic способ создания длинной многострочной строки

1307

У меня очень длинный запрос. Я хотел бы разбить его на несколько строк в 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
Пабло Мешер
источник
208
Поскольку ваш пример выглядит как блок SQL, ожидающий атаки с использованием инъекций, еще одно предложение - изучить библиотеку SQL более высокого уровня, такую ​​как SQLAlchemy, или что-то, что поможет избежать взлома необработанного SQL, подобного этому. (Возможно, не по теме, но вы просили «Любые предложения»;)
Джон Гейнс младший
6
Это «Pythonic способ создания многострочного кода для длинной строки». Чтобы создать строку, содержащую строки, см. Textwrap.dedent .
Боб Стейн
8
@cezar Я написал этот вопрос более пяти лет назад, но я помню, что он возник из-за незнания того, как правильно разместить длинный SQL-запрос в несколько строк. Я согласен, что я делал глупые вещи с этой длинной строкой, но это был не мой вопрос, и я не был достаточно умен, чтобы искать лучший пример, чтобы проиллюстрировать его, который не включал некоторые проблемы с внедрением SQL.
Пабло Мешер
@cezar нет, это не проблема XY, в любом случае запрос лучше всего отформатировать в несколько строк. SQLi не имеет отношения к рассматриваемому вопросу. Большие смелые предупреждения, однако, полностью оправданы :)
bugmenot123
Я написал небольшой пакет для этого. Пример здесь: stackoverflow.com/a/56940938/1842491
Шей

Ответы:

2229

Вы говорите о многострочных строках? Легко, используйте тройные кавычки, чтобы начать и закончить их.

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

Запятые не требуются, просто поместите строки, которые нужно объединить, в пару круглых скобок и обязательно учтите все необходимые пробелы и символы новой строки.

Левон
источник
8
Я предпочитаю явно использовать оператор «+» для второго метода. Не очень хлопотно и улучшает читабельность.
Марко Сулла
38
@LucasMalor Смежные строки являются конкатенацией во время компиляции. Разве использование +оператора не приводит к конкатенации во время выполнения?
Джошуа Тейлор
13
Для справки вот официальные документы по этому явлению: docs.python.org/2/reference/… (python 2) и docs.python.org/3/reference/… (python 3)
neverendingqs
4
Ваш пример хорош, но я хотел бы, чтобы он включал демонстрацию того, как безопасно и надежно встраивать переменные данные в запрос. И код примера OP, и пример @jessee показывают, как НЕ делать это правильно (это приглашение к атакам SQL). Смотрите также: dev.mysql.com/doc/connector-python/en/…
Скотт Прайв
2
Вы можете использовать textwrap.dedentдля удаления нежелательных ведущих пробелов. docs.python.org/3/library/textwrap.html#textwrap.dedent
Кори Голдберг,
190

Если вам не нужна многострочная строка, а просто длинная однострочная строка, вы можете использовать скобки, просто убедитесь, что вы не включаете запятые между строковыми сегментами, тогда это будет кортеж.

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, подобном тому, что вы строите, многострочные строки также подойдут. Но если бы дополнительный пробел, содержащийся в многострочной строке, был бы проблемой, тогда это был бы хороший способ достичь того, чего вы хотите.

Джесси
источник
1
@Pablo, вы можете даже добавить комментарии после,
Ashwini Chaudhary
@ 200OK ты имеешь в виду после '?
Кон Псих
3
Другой способ отформатировать эту строку - добавить .format(...)после закрывающей скобки. %форматирование нотации тоже должно работать, но я не пробовал
kon psych
3
Обратите внимание, что каждая строка должна заканчиваться строковой константой, поэтому ' foo '+variableне будет работать, но ' foo '+variable+''будет работать.
Йоо
46
Этот пример является открытой дверью для атак с использованием SQL-инъекций. Пожалуйста, никто не использует это в публичных приложениях. См. Документы MySQL для получения информации о том, как использовать «заполнители»: dev.mysql.com/doc/connector-python/en/…
Скотт Прайв
138

Прерывание линий \работает для меня. Вот пример:

longStr = "This is a very long string " \
        "that I wrote to help somebody " \
        "who had a question about " \
        "writing long strings in Python"
amphibient
источник
9
Я бы предпочел либо нотацию с тройными кавычками, либо обтекание внутри () символу \
Хан Хуа
15
Я настоятельно советую ставить пробелы в начале следующих строк, а не в конце следующих. Таким образом, случайно пропущенный является более очевидным (и, следовательно, с меньшей вероятностью произойдет).
Alfe
Также работает с переменными в конце строкlongStr = "account: " + account_id + \ ...
frmbelz
Я получаю следующую ошибку: the backslash is redundant between bracketsкогда я писал изнутриprint()
Alper
50

Я нашел себя счастливым с этим:

string = """This is a
very long string,
containing commas,
that I split up
for readability""".replace('\n',' ')
Ээро Аалтонен
источник
32
Не согласен. Что если первая строка ("string = ...") имеет большой отступ? Можно было бы сделать следующие строки с нулевым отступом, который выглядит некрасиво в середине блока с другим отступом.
xjcl
1
Ну, большинство моих длинных строк происходит на уровне модуля, где это прекрасно вписывается. В вашем случае, хотя это, очевидно, не будет лучшим решением.
Ээро Аалтонен
1
Мне нравится этот подход, потому что он дает право на чтение. В тех случаях, когда у нас длинные строки, это невозможно ... В зависимости от уровня отступа, в котором вы находитесь, и по-прежнему ограничено 80 символами в строке ... Ну ... Больше ничего не нужно говорить. На мой взгляд, руководства по питонскому стилю все еще очень расплывчаты. Спасибо!
Эдуардо Лусио
Это было бы так некрасиво, если бы оно использовалось под модулем, я тоже должен.replace('\t','')
Альпер
44

Я обнаружил, что при построении длинных строк вы обычно делаете что-то вроде создания SQL-запроса, и в этом случае это лучше всего:

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

То, что предложил Левон, хорошо, но может быть уязвимо для ошибок:

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

query == "SELECT fooFROM barWHERE baz"  # probably not what you want
darkfeline
источник
8
+1 Освобождает рецензента кода от необходимости тщательно проверять правый конец каждой строки на предмет нехватки пробелов . ФП совершил эту ошибку несколько раз, как отмечает @KarolyHorvath.
Боб Стейн
2
При просмотре многострочных строк, закодированных аналогичным образом, для простоты подтверждения мне требуются достаточные пробелы в левом конце каждой строки.
Зонт
3
@ BobStein-VisiBone Обзоры кода не должны быть связаны с синтаксическими ошибками или небольшими ошибками, как это, они должны быть о сути. Если кто-то выставляет код на проверку с синтаксическими ошибками (и поэтому не запускается вообще или в определенных ситуациях), тогда что-то серьезно не так. Это не трудно запустить ворсинку, прежде чем совершить. Если человек не заметил, что его программа не работает правильно, потому что он сделал такую ​​очевидную ошибку, он не должен совершать.
Чарльз Аддис
1
Согласовано @CharlesAddis, проверки кода должны проводиться после автоматических методов, например, lint, подсветки синтаксиса и т. Д. Однако некоторые ошибки, связанные с пробелами, могут быть не обнаружены таким образом. Я предлагаю все разумные преимущества в защите от ошибок.
Боб Стейн
33

Вы также можете объединять переменные при использовании нотации "" ":

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)
gjgjgj
источник
26

Этот подход использует:

  • только одна обратная косая черта, чтобы избежать начального перевода строки
  • почти нет внутренней пунктуации при использовании строки в тройных кавычках
  • удаляет локальный отступ с помощью inspect модуля textwrap
  • использование Python 3.6 отформатированной строки интерполяции ( «F») для account_idи def_idпеременных.

Этот способ выглядит наиболее питонным для меня.

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

Обновление : 29.01.2009 Включить предложение @ ShadowRanger для использования inspect.cleandocвместоtextwrap.dedent

Кристофер Брунс
источник
5
Примечание: inspect.cleandocнемного лучше , чем textwrap.dedent, поскольку он не требует первой линии , чтобы быть пустыми с символом продолжения строки в конце.
ShadowRanger
2
@ ShadowRanger Вау, я никогда не использовал cleandoc раньше. Я обновил свой ответ и буду в будущем использовать inspect.cleandocдля этого.
Кристофер Брунс
23

В 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}'''
Влад Безден
источник
4
Как будет работать f-строка, если я захочу записать результат многострочной строки и не показывать левые табуляции / пробелы?
17
7
По-прежнему уязвимы для SQL-инъекций
Трентон
19

Например:

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'"
pangpang
источник
13

Я нахожу textwrap.dedentлучшее для длинных строк, как описано здесь :

def create_snippet():
    code_snippet = textwrap.dedent("""\
        int main(int argc, char* argv[]) {
            return 0;
        }
    """)
    do_something(code_snippet)
Фредрик
источник
1
Мне нравится черная косая черта, которая мешает авто новой линии, большое спасибо!
Зы
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,'      \
    'her sheep would surely go.'
# => SyntaxError: unexpected character after line continuation character

Лучшие комментарии для строк Regex:

Основываясь на примере с 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)
ddrscott
источник
10

Лично я считаю, что следующий способ - лучший (простой, безопасный и Pythonic) способ написания необработанных SQL-запросов на Python, особенно при использовании модуля sqlite3 в 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 = ?
        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

Pros

  • Аккуратный и простой код (Pythonic!)
  • Сейф от внедрения SQL
  • Совместим с Python 2 и Python 3 (это Pythonic в конце концов)
  • Конкатенация строк не требуется
  • Не нужно гарантировать, что самый правый символ каждой строки является пробелом

Cons

  • Поскольку переменные в запросе заменяются ?местозаполнителем, может оказаться немного сложным отследить, какую из них ?заменить какой переменной Python, когда их много в запросе.
Faheel
источник
Обратите внимание, я не проверял это, но вы, вероятно, можете избежать путаницы с вопросительными знаками, заменив их на "{0} {1} {2}" в соответствующих местах, а затем изменив последнюю строку на cursor.execute(query.format(vars)). Это должно заботиться о вашем единственном "мошенничестве" (я надеюсь).
Бен
Да, использование formatбыло бы неплохо, но я не уверен, будет ли строка запроса, отформатированная таким образом, безопасна для внедрения SQL.
Фахил
Да, это справедливо, и это может быть немного сложно. Возможно, было бы разумно протестировать его на чем-то полностью расходуемом ... без сомнения, Comp. Sci. старшекурсник скоро пройдет. ;)
Бен
2
@Ben, если вам это cursor.execute(query.format(vars))не нужно, вы больше не получаете прибыль от подготовленных операторов, так что вы уязвимы для многих видов проблем, начиная с того факта, что если параметры не просто числа, вам нужно заключить их в кавычки в SQL-запросе.
Патрик Мевзек
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())
Израиль Барт Рубио
источник
2
Посмотрите на textwrap.dedentфункцию Python , которая находится в стандартной библиотеке, она обладает необходимой вам функциональностью.
bjd2385
@ bjd2385: inspect.cleandocнемного лучше (менее требователен к тому, появляется ли текст в той же строке, что и открытые кавычки, не требует явных символов продолжения строки).
ShadowRanger
3

Ваш фактический код не должен работать, вам не хватает пробельные в конце «линии» (например: role.descr as roleFROM...)

Для многострочной строки есть тройные кавычки:

string = """line
  line2
  line3"""

Он будет содержать разрывы строк и лишние пробелы, но для SQL это не проблема.

Каролий хорват
источник
3

Вы также можете поместить SQL-оператор в отдельный файл action.sqlи загрузить его в py-файл с помощью

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

Таким образом, SQL-операторы будут отделены от кода Python. Если в выражении sql есть параметры, которые необходимо заполнить из python, вы можете использовать форматирование строки (например,% s или {field})

mrijken
источник
3

Путь "а- ля" Скала (но я думаю, что это самый питонический путь, как того требует 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('            | ',' ')

Если вам нужен последний str без переходов, просто поместите \nв начале первого аргумента второй замены:

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

Примечание: белая линия между «... шаблонами». и "Кроме того ..." требует пробела после |.

victe
источник
3

tl; dr: используйте """\и """для переноса строки , как в

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

Из официальной документации по питону :

Строковые литералы могут занимать несколько строк. Одним из способов является использование тройных кавычек: "" "..." "" или "" ... ". Конец строк автоматически включается в строку, но это можно предотвратить, добавив \ в конце строки. Следующий пример:

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
поток
источник
2

Эй, попробуйте что-то вроде этой надежды, это работает, как в этом формате, он вернет вам непрерывную строку, как вы успешно спросили об этом свойстве`

"message": f'you have successfully inquired about '
           f'{enquiring_property.title} Property owned by '
           f'{enquiring_property.client}'
Кельвин Онкунди
источник
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)

PS: взгляните на потрясающую библиотеку python-sqlparse, чтобы при необходимости распечатывать запросы SQL. http://sqlparse.readthedocs.org/en/latest/api/#sqlparse.format

Sandeep
источник
"рекурсивная функция", разве это не называется лямбда?
m3nda
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 
Эяль Левин
источник
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!
    """)
Джошуа Холл
источник
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
)
"""
Эдуардо Лучио
источник
0

Из официальной документации по питону :

Строковые литералы могут занимать несколько строк. Одним из способов является использование тройных кавычек: "" "..." "" или "" ... ". Конец строк автоматически включается в строку, но это можно предотвратить, добавив \ в конце строки. Следующий пример:

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

производит следующий вывод (обратите внимание, что начальный перевод строки не включен):

поток
источник
0

Для определения длинной строки внутри dict, сохранения новых строк, но без пробелов , я в итоге определил строку в константе, подобной этой:

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

my_dict = {
   'foo': 'bar',
   'string': LONG_STRING
}
Фликс
источник
0

В качестве общего подхода к длинным строкам в 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

Изменить: этот подход не соответствует PEP8, но я считаю его полезным иногда

Расмус Грот
источник
-7

Вообще, я использую listи joinдля многострочных комментариев / строк.

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' (новая строка ) или ' ,' (запятая) или ' ' (пробел)

Ура .. !!

Paone
источник
1
Почему бы вам не использовать массив по крайней мере?
Александр - Восстановить Монику
1
Массивы представлены списком классов. проверьте другое обсуждение относительно литералов массива
paone
Я полагаю, это работает, но вы должны думать о производительности и удобочитаемости ...
Petro