Pythonic способ создания длинной многострочной строки
У меня очень длинный запрос. Я хотел бы разбить его на несколько строк в 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
Ответы
Ответ 1
Вы говорите о многострочных строках? Легко, используйте тройные кавычки, чтобы начать и завершить их.
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 ...'
Никаких запятых не требуется, просто поместите строки для объединения в пару круглых скобок и обязательно учтите любые необходимые пробелы и символы новой строки.
Ответ 2
Если вам не нужна многострочная строка, а просто длинная одиночная строка, вы можете использовать круглые скобки, просто убедитесь, что вы не включаете запятые между строковыми сегментами, тогда это будет кортеж.
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, как то, что вы строите, многострочные строки также будут в порядке. Но если бы лишние пробелы, которые содержала бы многострочная строка, были бы проблемой, тогда это было бы хорошим способом добиться того, чего вы хотите.
Ответ 3
Разделительные линии \
работают для меня. Вот пример:
longStr = "This is a very long string " \
"that I wrote to help somebody " \
"who had a question about " \
"writing long strings in Python"
Ответ 4
Я был доволен этим:
string = """This is a
very long string,
containing commas,
that I split up
for readability""".replace('\n',' ')
Ответ 5
Я нахожу, что при построении длинных строк вы обычно делаете что-то вроде построения 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
Ответ 6
Вы также можете объединить переменные при использовании обозначения "":
foo = '1234'
long_string = """fosdl a sdlfklaskdf as
as df ajsdfj asdfa sld
a sdf alsdfl alsdfl """ + foo + """ aks
asdkfkasdk fak"""
EDIT: Найден лучший способ с именованными параметрами и .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)
Ответ 7
В 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}'''
Ответ 8
Этот подход использует:
-
только одна обратная косая черта, чтобы избежать начального перевода строки - почти нет внутренней пунктуации при использовании строки в тройных кавычках
- удаляет локальные отступы с помощью модуля
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.2009 Включение предложения @ShadowRanger для использования inspect.cleandoc
вместо textwrap.dedent
Ответ 9
Например:
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'"
Ответ 10
Я считаю textwrap.dedent
лучшим для длинных строк, как описано здесь:
def create_snippet():
code_snippet = textwrap.dedent("""\
int main(int argc, char* argv[]) {
return 0;
}
""")
do_something(code_snippet)
Ответ 11
Лично я считаю, что лучшим (простым, безопасным и Pythonic) способом написания необработанных SQL-запросов на Python является следующий, особенно при использовании модуля 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 sqlite3 module
Pros
- Аккуратный и простой код (Pythonic!)
- Безопасно от SQL-инъекции
- Совместим с Python 2 и Python 3 (это Pythonic в конце концов)
- Конкатенация строк не требуется
- Не нужно гарантировать, что самый правый символ каждой строки является пробелом
Cons
- Поскольку переменные в запросе заменены на
?
заполнитель, может стать немного трудно отслеживать, что ?
должна быть заменена на какую переменную Python, когда их много в запросе.
Ответ 12
Я обычно использую что-то вроде этого:
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())
Ответ 13
Ваш фактический код не должен работать, вам не хватает пробелов в конце "строк" (например: role.descr as roleFROM...
)
Существует три раза для многострочной строки:
string = """line
line2
line3"""
Он будет содержать разрывы строк и дополнительные пробелы, но для SQL это не проблема.
Ответ 14
Вы также можете поместить sql-инструкцию в отдельный файл action.sql
и загрузить его в файл py с помощью
with open('action.sql') as f:
query = f.read()
Таким образом, sql-операторы будут отделены от кода python. Если в операторе sql есть параметры, которые необходимо заполнить из python, вы можете использовать форматирование строк (например,% s или {field})
Ответ 15
"À la" Scala (но я думаю, что это самый пифонический путь, который требует 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(' | ',' ')
Если вы хотите окончательную строку без линий перехода, просто поставьте \n
в начале первого аргумента второй замены:
.replace('\n | ',' ')`.
Примечание: белая линия между "... шаблонами". и "Кроме того..." требует пробела после |
.
Ответ 16
Я использую рекурсивную функцию для создания сложных 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
Ответ 17
Другой вариант, который, по моему мнению, более читабельен, когда код (например, переменная) имеет отступ, а выходная строка должна быть одним лайнером (без символов новой строки):
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
Ответ 18
Другие уже упоминали метод круглых скобок, но я хотел бы добавить, что с круглыми скобками разрешены встроенные комментарии.
Прокомментируйте каждый фрагмент:
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
ошибки 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)
Ответ 19
Мне нравится этот подход, потому что он дает право на чтение. В тех случаях, когда у нас длинные струны, это невозможно! В зависимости от уровня отступа вы находитесь и до сих пор ограничены 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
)
"""
Ответ 20
Эй, попробуйте что-то вроде этой надежды, это работает, как в этом формате, он вернет вам непрерывную линию, как вы успешно спросили об этом свойстве.
"message": f'you have successfully inquired about '
f'{enquiring_property.title} Property owned by '
f'{enquiring_property.client}'
Ответ 21
Обычно я использую 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
' (новая строка) или ' ,
' (запятая) или '
'(пространство)
Ура.. !!