Строка форматирования именованных параметров?

135

Я знаю, что это действительно простой вопрос, но я не знаю, как его погуглить.

Как я могу сделать

print '<a href="%s">%s</a>' % (my_url)

Так что my_urlиспользуется дважды? Я предполагаю, что должен «назвать» %sи затем использовать dict в параметрах, но я не уверен в правильном синтаксисе?


просто к сведению, я знаю, я могу просто использовать my_urlдважды в параметрах, но это не главное :)

mpen
источник
Название вопроса немного вводит в заблуждение. Это не имеет ничего общего с оператором print, просто с тем, как работает интерполяция строк.
Грег Болл
Если вы не знаете, как его найти, перейдите по этой ссылке: python.org/doc . Это лучше, чем Google по одной важной причине.
S.Lott

Ответы:

80

В Python 2.6+ и Python 3 вы можете использовать более новый метод форматирования строк.

print('<a href="{0}">{0}</a>'.format(my_url))

который спасает вас от повторения аргумента, или

print('<a href="{url}">{url}</a>'.format(url=my_url))

если вы хотите именованные параметры.

print('<a href="{}">{}</a>'.format(my_url, my_url))

который является строго позиционным и поставляется только с оговоркой, что аргументы format () следуют правилам Python, где сначала должны стоять безымянные аргументы, за которыми следуют именованные аргументы, за которыми следуют * args (последовательность вроде list или tuple) и затем * kwargs (dict под ключ со строками, если вы знаете, что хорошо для вас). Точки интерполяции определяются сначала путем подстановки именованных значений по их меткам, а затем позиционно из того, что осталось. Итак, вы также можете сделать это ...

print('<a href="{not_my_url}">{}</a>'.format(my_url, my_url, not_my_url=her_url))

Но не это ...

print('<a href="{not_my_url}">{}</a>'.format(my_url, not_my_url=her_url, my_url))
Грег Болл
источник
Приятно видеть, как влияние
меняется
3
Вышеуказанный метод не предназначен для форматирования именованных строк, однако это позиционное форматирование строк. Так что это на самом деле не отвечает на вопрос.
'11
"literal {arg1}".format(arg1="arg!")Названный формат работает с Python 3.5, в то время как terser f"literal {arg1}"это новая инновация в Python 3.6 или новее, AFAIK.
MarkHu
218
print '<a href="%(url)s">%(url)s</a>' % {'url': my_url}
Игнасио Васкес-Абрамс
источник
3
Я предпочитаю создавать диктат с помощью kwargs:'<a href="%(url)s">%(url)s</a>' % dict(url=my_url)
schlamar
11
Интересно, почему вы предпочитаете это чмламар? Я бы не сразу понял, что это значит, сравнив обычную декларацию диктата, который использует ОП ...
GreenAsJade
1
В документации не говорится, когда это было введено, так что это, вероятно, во всех версиях Python 2.
Евгений Сергеев
2
Используйте format (), если можете, это работает лучше и в большем количестве мест. Используйте%, если вы ДОЛЖНЫ.
Учуугака
39

Решение в Python 3.6+

Python 3.6 вводит форматирование буквенных строк , так что вы можете форматировать именованные параметры без повторения каких-либо из ваших именованных параметров вне строки:

print(f'<a href="{my_url:s}">{my_url:s}</a>')

Это оценит my_url, поэтому, если он не определен, вы получите NameError. Фактически вместо этого my_urlвы можете написать произвольное выражение Python, если оно вычисляется в строку (из-за :sкода форматирования). Если вы хотите получить строковое представление для результата выражения, которое может не быть строкой, замените :sего !s, как при обычном предлитеральном форматировании строки.

Подробнее о форматировании литеральных строк см. PEP 498 , где он был впервые представлен.

Геррит
источник
1
Кажется, что PEP не охватывает все форматеры; Я думаю, что они такие же, как str.format, который описан
mpen
6

Вы будете зависимы от синтаксиса.

Также C # 6.0, разработчики EcmaScript также знакомы с этим синтаксисом.

In [1]: print '{firstname} {lastname}'.format(firstname='Mehmet', lastname='Ağa')
Mehmet Ağa

In [2]: print '{firstname} {lastname}'.format(**dict(firstname='Mehmet', lastname='Ağa'))
Mehmet Ağa
guneysus
источник
5

Для построения HTML-страниц вы хотите использовать шаблонизатор, а не простую интерполяцию строк.

Майк Грэм
источник
2
Шаблонный движок Django также может оказаться идеальным инструментом для писем, которые вы делаете.
Майк Грэм,
6
Что мешает вам использовать шаблон Django для создания тела письма с его render()методом? Ничто не говорит о том, что вы должны кормить шаблон вывода HttpResponse(). Джанго смущающе универсален.
Майк Де Симоне
1
@Mike: Я думал, что у Django может быть решение для этого тоже, но я еще не нашел его: p Тогда я, вероятно, перенесу свои электронные письма в шаблоны! Спасибо. Может быть, я запутался, но я обнаружил, что в некоторых областях это довольно жестко.
mpen
2
@ случайные люди, которые читают эти комментарии: более подробную информацию о том, как это сделать, можно найти
mpen
1
Для комментирования вопросов вы хотите использовать комментарии, а не ответы.
Suriv
2

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

print '<a href="%s">%s</a>' % (my_url, my_url)

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

Ponkadoodle
источник
Я только что сказал парню, что предложил это :) Он удаляет свой пост. Я чувствую себя немного плохо сейчас. Да, я знаю, что могу сделать это, но это было не то, что я искал. Как вы сказали, это избыточно, и my_urlна самом деле это вызов функции, который я не хочу оценивать дважды. Дважды не так уж плохо, но это могло бы быть легко 20 раз :)
mpen
5
Я подумал, что оставлю свой на всякий случай, если это поможет кому-то другому. Ну, словарный путь, вероятно, лучший путь. Но для избыточности, (get_my_url(), )*20только вызывает функцию один раз и дублирует ее 20 раз.
Ponkadoodle