На этом шаге мы рассмотрим, в чем заключается этот метод.
Еще один прием форматирования строк в Python представлен шаблонными строками. Этот механизм более простой и менее мощный, но в некоторых случаях он может оказаться именно тем, что вы ищете.
Давайте взглянем на простой пример приветствия:
>>> from string import Template >>> t = Template('Эй, $name!') >>> t.substitute(name=name) 'Эй, Боб!'
Здесь вы видите, что нам приходится импортировать класс Template из встроенного модуля Python string. Шаблонные строки не являются ключевым функциональным свойством языка, но они обеспечиваются модулем стандартной библиотеки.
Еще одно отличие состоит в том, что шаблонные строки не допускают спецификаторы формата. Поэтому, чтобы заставить пример со строковой ошибкой работать, мы должны сами преобразовать целочисленный код ошибки в шестнадцатеричное строковое значение:
>>> templ_string = 'Эй, $name! Вот ошибка $error!' >>> Template(templ_string).substitute(name=name, error=hex(errno)) 'Эй, Боб! Вот ошибка 0xbadc0ffee!'
Пример сработал отлично, но вы, вероятно, интересуетесь, в каких случаях использовать шаблонные строки в программах на Python. На наш взгляд, самый лучший вариант применения шаблонных строк наступает тогда, когда вы обрабатываете форматные строки, сгенерированные пользователями программы. Благодаря их уменьшенной сложности, шаблонные строки являются более безопасным вариантом выбора.
Более сложные мини-языки форматирования для других приемов форматирования строк могут вносить уязвимости в ваши программы с точки зрения безопасности. Например, форматные строки могут получать доступ к произвольным переменным в программе.
Это означает, что если злонамеренный пользователь может передать форматную строку, то он также может потенциально раскрыть секретные ключи и другую ценную информацию! Вот простое доказательство идеи о том, как такая атака могла бы использоваться:
>>> SECRET = 'это - секрет' >>> class Error: def __init__(self): pass >>> err = Error() >>> user_input = '{error.__init__.__globals__[SECRET]}' # Ой-ой-ой >>> user_input.format(error=err) 'это - секрет'
Заметили, как гипотетический взломщик смог извлечь нашу секретную строку, обратившись из форматной строки к словарю __globals__? Жутко, да! Шаблонные строки закрывают это направление атаки, и это делает их более безопасным выбором, если вы обрабатываете форматные строки, генерируемые из данных, вводимых пользователем:
>>> user_input = '${error.__init__.__globals__[SECRET]}' >>> Template(user_input).substitute(error=err) Traceback (most recent call last): ValueError: Invalid placeholder in string: line 1, col 1
На следующем шаге мы рассмотрим какой метод форматирования строк использовать.