Пітонічний спосіб створення довгої багаторядкової струни


1304

У мене дуже довгий запит. Я хотів би розділити його на кілька рядків у 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

207
Оскільки ваш приклад виглядає як блок SQL, який просто очікує на ін'єкційну атаку, інша пропозиція полягає в тому, щоб заглянути в бібліотеку SQL вищого рівня, як SQLAlchemy, або щось, щоб уникнути злому разом із цим сирого SQL. (Можливо, поза темою, але ви попросили "Будь-які пропозиції";)
Джон Гейнс-молодший

6
Це "Пітонічний спосіб створення багаторядкового коду для довгого рядка". Для створення рядка, що містить нові рядки, див. Textwrap.dedent .
Боб Штейн

8
@cezar Я писав це питання більше п'яти років тому, але пам’ятаю, що воно виникло з того, що я не знав, як правильно поставити довгий запит sql в кілька рядків. Я погоджуюся, що я робив дурні речі з такою довгою струною, але це не було моїм питанням, і я не був достатньо розумним, щоб шукати кращий приклад, щоб проілюструвати це, що не включало деяких проблем з введенням sql.
Пабло Мешер

@cezar ні, це не проблема XY, запит найкраще відформатувати в декількох рядках у будь-якому випадку. SQLi не пов'язаний з питанням. Однак великі сміливі попередження цілком виправдані :)
bugmenot123

Я написав для цього невеликий пакет. Приклад тут: stackoverflow.com/a/56940938/1842491
Шай

Відповіді:


2225

Ви говорите про багаторядкові рядки? Легко, використовуйте потрійні лапки, щоб почати та закінчити їх.

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
Corey Goldberg

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 ви маєте на увазі після '?
kon psych

3
Іншим способом форматування цього рядка було б додавання .format(...)після дужки, що закривається. %Форматування позначень теж має працювати, але я цього не пробував
kon psych

3
Зауважте, що кожен рядок повинен закінчуватись постійною рядком, тому ' foo '+variableне буде працювати, але ' foo '+variable+''буде.
yoyo

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"

9
Я вважаю за краще або позначення потрійної цитати, або обгортання всередині () символу \
Хан Хуа

14
Я настійно раджу розміщувати пробіли на початку наступних рядків, а не в кінці наступних рядків. Таким чином випадково відсутній спосіб є більш очевидним (і, таким чином, це менш ймовірно).
Альфе

Також працює зі змінними в кінці рядківlongStr = "account: " + account_id + \ ...
frmbelz

Я отримую таку помилку: the backslash is redundant between bracketsколи я писав всерединуprint()
Альпер

50

Я був щасливий з цим:

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

30
Не згоден. Що робити, якщо перший рядок ("string = ...") сильно зрізаний? Потрібно було б виділити наступні рядки до нульового відступу, який виглядає некрасиво посеред блоку, що має відступ.
xjcl

1
Ну, більшість моїх тривалих рядків відбувається на рівні модуля, де це добре вписується. У вашому випадку, хоча це, очевидно, не буде найкращим рішенням.
Eero Aaltonen

1
Мені подобається такий підхід, оскільки він привілейовує читання. У випадках, коли у нас довгі рядки, немає способу ... Залежно від рівня відступу, який ви перебуваєте, і все ще обмежений 80 символами на рядок ... Ну ... Не потрібно нічого більше говорити. На мій погляд, посібники зі стилю пітона все ще дуже розпливчасті. Дякую!
Едуардо Лусіо

Це було б так потворно, якби його використовували під модулем, я також повинен.replace('\t','')
alper

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

8
+1 Знімає рецензента коду від необхідності старанно перевіряти правильний кінець кожного рядка на відсутність пробілу . ОП зазнала помилку кілька разів, як зазначає @KarolyHorvath.
Боб Штейн

2
Переглядаючи багаторядкові рядки, кодовані подібним чином, я потребую належного пробілу в лівій частині кожного рядка для легкого підтвердження.
Парасолька

3
@ Огляд коду BobStein-VisiBone не повинен стосуватися синтаксичних помилок або маленьких помилок на кшталт цього, вони повинні стосуватися суті. Якщо хтось ставить код на огляд, у якому є синтаксичні помилки (і, таким чином, не працюватимуть ні взагалі, ні в певних ситуаціях), то щось серйозно не так. Не важко запустити ворсинку, перш ніж здійснити. Якщо людина не помітила, що їх програма не працює належним чином, тому що вони допустили таку очевидну помилку, вона не повинна здійснювати.
Чарльз Аддіс

1
Погоджено @CharlesAddis, огляд коду повинен надходити після автоматизованих методів, наприклад, підсвічування, підкреслення синтаксису тощо. Однак деякі помилки, відсутніх у пробілі, можуть не потрапляти таким чином. Я пропоную використати всі розумні переваги в захисті від помилок.
Боб Штейн

33

Ви також можете об'єднати змінні, використовуючи позначення "" ":

foo = '1234'

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

EDIT: Знайдено кращий спосіб з назвами params та .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)

26

Цей підхід використовує:

  • лише один зворотний нахил, щоб уникнути початкової передачі ліній
  • майже немає внутрішньої пунктуації за допомогою потрійного цитованого рядка
  • знімає місцеве відступ за допомогою модуля textwrap inspect
  • використовує інтерполяцію рядка у форматі 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.2019 Включіть пропозицію @ ShadowRanger використовувати inspect.cleandocзамість цьогоtextwrap.dedent


5
Примітка: inspect.cleandocтрохи краще , ніж textwrap.dedent, оскільки він не вимагає першої лінії , щоб бути порожніми з символом продовження рядка в кінці.
ShadowRanger

2
@ShadowRanger Нічого раніше я ніколи не використовував clendoc. Я оновив свою відповідь і буду надалі використовувати inspect.cleandocдля цього.
Крістофер Брунс

23

У Python> = 3.6 ви можете використовувати відформатовані рядкові літерали (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}'''

4
Як би працював f-string, якщо я хотів зафіксувати результат багаторядкового рядка і не відображати ліві бічні вкладки / пробіли?
kuanb

7
Все ще вразлива до ін'єкцій SQL
Trenton

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

13

Я вважаю textwrap.dedentнайкращим для довгих рядків, як описано тут :

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

1
Мені подобається чорна коса риса, яка перешкоджає автоматичній новій лінії, дуже дякую!
zyy

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)

10

Я особисто вважаю, що найкращим (простим, безпечним та пітонічним) способом написання необроблених запитів 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

Плюси

  • Акуратний і простий код (Pythonic!)
  • Безпечно від ін'єкції SQL
  • Сумісний і з Python 2, і з Python 3 (це все-таки Pythonic)
  • Не потрібно з'єднання рядків
  • Не потрібно гарантувати, що найправішим символом кожного рядка є пробіл

Мінуси

  • Оскільки змінні в запиті замінюються ?заповнювачем, може бути важко відслідковувати, яку ?слід замінити, якою змінною Python, коли їх у запиті багато.

Зауважте, я цього не перевіряв, але ви, ймовірно, можете уникнути плутанини запитального знака, замінивши їх у відповідних місцях на "{0} {1} {2}" та змінивши останній рядок на cursor.execute(query.format(vars)). Це має подбати про ваш єдиний "кон" (сподіваюся).
Бен

Так, використання formatбуло б непогано, але я не впевнений, чи форматована таким чином рядок запиту була б захищеною від інжекції SQL.
Faheel

Так, це справедливо, і це, безумовно, може бути трохи хитро. Можливо, перевірити це на чомусь цілком витратному було б розумно ... без сумніву, Comp. Наук. Undergrad пройде повз досить скоро. ;)
Бен

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


3

Шкала "À la" Scala (але, на мою думку, це найбільш пітонічний спосіб, як вимагає ОК):

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

Якщо ви хочете остаточну \nстроку без стрибків, просто поставте на початку першого аргументу другу заміну:

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

Примітка: біла лінія між "... шаблонами". та "Також ..." потрібен пробіл після |.


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


"рекурсивна функція" не називається лямбда?
м3нда

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

Що стосується питання ОП, що стосується запиту 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" (новий рядок) або " ," (кома) або " " (пробіл)

Ура .. !!


1
Чому б ти хоча б не використав літерал масиву?
Олександр - Відновіть Моніку


Я думаю, це працює, але ви повинні подумати про продуктивність та читаність ...
Петро,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.