Расширенное форматирование строк и строк шаблонов
Мне было интересно, есть ли преимущество использования строк шаблона вместо нового форматирования форматированных строк
Ответы
Ответ 1
Шаблоны должны быть проще, чем обычное форматирование строк, ценой выразительности. Обоснование PEP 292 сравнивает шаблоны с форматированием строки Python %
:
В настоящее время Python поддерживает синтаксис подстановки строк, основанный на C printf()
'%' символ форматирования. Будучи довольно богатым, % -форматирующие коды также подвержены ошибкам, даже для опытных программистов на Python. Общей ошибкой является отказ от символ заднего символа, например. s
в %(name)s
.
Кроме того, правила того, что может следовать за знаком%, справедливы а обычное приложение редко требует такой сложности. Большинство скриптов должны выполнять некоторую строчную интерполяцию, но большая часть те используют простой stringification' formats, i.e.
% s or
% (name) s` Эта форма должна быть упрощена и менее подвержена ошибкам.
В то время как новый .format()
улучшил ситуацию, все же верно, что синтаксис строки довольно сложный, поэтому в обосновании все еще есть точек.
Ответ 2
Для того, что стоит, замена шаблона из dict в 4-10 раз медленнее, чем замена формата, в зависимости от длины шаблона. Здесь быстрое сравнение я побежал под OS X на ядре i7 2.3 ГГц с Python 3.5.
from string import Template
lorem = "Lorem ipsum dolor sit amet {GIBBERISH}, consectetur adipiscing elit {DRIVEL}. Expectoque quid ad id, quod quaerebam, respondeas."
loremtpl = Template("Lorem ipsum dolor sit amet $GIBBERISH, consectetur adipiscing elit $DRIVEL. Expectoque quid ad id, quod quaerebam, respondeas.")
d = dict(GIBBERISH='FOOBAR', DRIVEL = 'RAXOOP')
In [29]: timeit lorem.format(**d)
1.07 µs ± 2.13 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
In [30]: timeit loremtpl.substitute(d)
8.74 µs ± 12.9 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
Самый худший случай, который я тестировал, был примерно в 10 раз медленнее для строки из 13 символов. Самый лучший случай, который я тестировал, был примерно в 4 раза медленнее для строки в 71000 символов.
Ответ 3
Одним из ключевых преимуществ строковых шаблонов является то, что вы можете заменить только некоторые из заполнителей, используя метод safe_substitute
. Строки нормального формата вызовут ошибку, если заполнитель не передал значение. Например:
"Hello, {first} {last}".format(first='Joe')
возникает:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'last'
Но:
from string import Template
Template("Hello, $first $last").safe_substitute(first='Joe')
Выдает:
'Hello, Joe $last'
Обратите внимание, что возвращаемое значение представляет собой строку, а не Template
; если вы хотите заменить $last
, вам нужно создать новый объект Template
из этой строки.
Ответ 4
В первую очередь это вопрос предпочтения синтаксиса, который обычно сводится к компромиссу лени/расширительности и привычки/привычки с существующими системами шаблонов строк. В этом случае строки шаблонов более ленивые/простые/быстрые для записи, а .format()
более подробные и полнофункциональные.
Программисты, используемые для языка PHP или семейства шаблонов Jinja, могут предпочесть шаблонные строки. Использование "% s" позиционной замены кортежа в стиле может понравиться тем, кто использует форматирование строки printf
или как-то быстро. .format()
имеет еще несколько функций, но если вам не требуется что-то конкретное, которое предоставляется только .format()
, нет ничего плохого в использовании любой существующей схемы.
Единственное, о чем нужно знать, это то, что именованные строковые шаблоны более гибкие и требуют меньшего обслуживания, чем зависящие от заказов. Помимо этого все сводится к личным предпочтениям или стандарту кодирования проекта, над которым вы работаете;