Форматування рядків з названими параметрами?


134

Я знаю, що це дійсно просте запитання, але я поняття не маю, як його гугл.

як я можу зробити

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

Так що my_urlвикористовується два рази? Я припускаю, що я повинен "назвати", %sа потім використати дік у парамах, але я не впевнений у правильному синтаксисі?


просто FYI, я знаю, що я можу просто my_urlдва рази використовувати парами, але це не сенс :)


Назва питання трохи вводить в оману. Це не має нічого спільного з оператором print, а саме з тим, як працює інтерполяція рядків.
Грег Бал Бал

Якщо ви не маєте уявлення про те, як це зробити в Google, перейдіть сюди, щоб скористатися пошуком: python.org/doc . Це краще, ніж Google з однієї важливої ​​причини.
С.Лотт

Відповіді:


79

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

що суворо позиціонується, і приходить лише з застереженням, що аргументи формату () слідують правилам Python, де спочатку мають бути названі аргументи, а потім іменні аргументи, потім * args (послідовність як список чи кортеж), а потім * 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))

Приємно бачити зміну впливу з ++ на #
cod3monk3y

3
Вищеописаний метод не для форматування рядків з назвою, але це позиційне форматування рядків. Тож це насправді не відповідає на питання.
jaapz

"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
Я вважаю за краще створити дикт з кворгами:'<a href="%(url)s">%(url)s</a>' % dict(url=my_url)
schlamar

11
Цікаво, чому ти вважаєш за краще цей шмаламар? Я б не знав, що це означає, порівнюючи звичайну декларацію
дикта, яку

1
У документації не зазначено, коли це було введено, тому, ймовірно, у всіх версіях Python 2.
Євгеній Сергєєв

2
Використовуйте формат (), якщо можете, він працює краще і в багатьох місцях. Використовуйте%, якщо ОБ'ЄДНО
uchuugaka

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, який задокументований тут: docs.python.org/3.4/library/string.html#formatstrings
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

5

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


2
Модель шаблону Джанго також може виявитися ідеальним інструментом для електронних листів, які ви робите.
Майк Грехем

6
Що вас заважає використовувати шаблон Django для створення тіла електронної пошти його render()методом? Ніщо не говорить про те, що вам потрібно подавати вихідний шаблон HttpResponse(). Джанго бентежно універсальний.
Майк Десимоне

1
@Mike: Я думав, що у Django теж може бути рішення для цього, але я його ще не знайшов: p Я, мабуть, перенесу свої електронні листи у шаблони! Дякую. Можливо, я відкладений, але в деяких районах я вважаю це досить жорстким.
mpen

2
@ випадкові люди, які читають ці коментарі: знайшли детальніше, як це зробити тут rossp.org/blog/2006/jul/11/sending-e-mails-templates
mpen

1
Щоб коментувати питання, ви хочете використовувати коментарі, а не відповіді.
suriv

2

Окрім словникового способу, може бути корисним наступний формат:

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

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


Я щойно сказав хлопцеві, що запропонував це :) Він видаляє свою посаду. Зараз я почуваюсь погано. Так, я усвідомлюю, що можу це зробити, але це було не те, що я шукав. Як ви сказали, це зайве, і my_urlце фактично виклик функції, який мені не хочеться оцінювати двічі. Двічі не так вже й погано, але це просто могло бути 20 разів :)
квітня

5
Я подумав, що збережу своє, на всякий випадок, якщо це допоможе комусь іншому. Що ж, словниковий шлях, мабуть, найкращий шлях. Але для надмірності (get_my_url(), )*20функція викликає лише один раз і дублює її 20 разів.
Ponkadoodle
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.