Форматирование строк в Python 2 использовало оператор % по модулю. Python 3 был выпущен в 2008 году и включал альтернативы форматированию строк: str.format()
. Перенесемся в 2016 год, когда Python 3.6 выпустил форматированные строковые литералы (или f-строки).
Может показаться иконоборчеством утверждение, что строки str.format
и f не всегда предпочтительнее старого стиля, но в самой документации Python говорится, что старый стиль может быть лучше в таких случаях, как ведение журнала. Этот пост в блоге объяснит, почему вы не должны использовать новое форматирование строк при ведении журнала.
Когда использовать новое форматирование строки вместо старого форматирования
Большинство считает F-строки более удобными, чем оператор %, и, возможно, их легче читать. Они также более гибкие и могут использоваться для интерполяции выражений Python в строку.
Как гласит дзен Python: читабельность имеет значение. Новый инструмент форматирования строк Python — отличный способ улучшить читаемость. Синтаксис очень похож на существующий синтаксис форматирования строк, но есть некоторые существенные отличия:
# old style. like printf in C print("Hello, %s!" % "world") print("The answer is %d" % 42) print("%f + %" = %" % (1, 2, 3))
Вы также можете использовать метод format() для форматирования строк. Это обеспечивает более гибкий синтаксис и позволяет использовать спецификации форматирования:
print("Hello, {0}!".format("world")) print("The answer is {0}".format(42)) print("{0} + {1} = {2}".format(1, 2, 3)
Строки шаблона позволяют встраивать код Python непосредственно в ваши строки, что может быть очень полезно для сложных задач форматирования:
import datetime t = datetime.date(2016, 1, 1) print("Today is {t.day}/{t.month}/{t.year}".format(t=t))
Новый подход к форматированию строк имеет несколько преимуществ:
- Он более гибкий и простой в использовании.
- Он поддерживает именованные аргументы, которые могут упростить чтение кода.
- Он поддерживает сложные объекты (такие как списки и словари), чего нет в старом подходе оператора %.
Старый подход с оператором % может быть предпочтительнее при работе с устаревшим кодом, потому что стабильно плохое предпочтительнее непостоянно хорошего, или (страшно подумать) библиотека, которая все еще поддерживает Python 2.7. Но в целом по возможности лучше использовать новый подход к форматированию строк.
В защиту старого форматирования строк
Старый стиль форматирования строк может быть предпочтительнее в соответствии с Документацией по регистрации Python.
Вход в Python 3
Модуль ведения журнала Python предоставляет мощную и гибкую платформу для создания сообщений журнала из программ Python. Ключевым моментом для этой оптимизации строки является то, что не каждый вызов регистратора отправляется в журнал в зависимости от конфигурации ведения журнала.
Самый простой способ настроить ведение журнала — вызвать функцию basicConfig()
. Это настроит модуль ведения журнала с набором параметров по умолчанию. После настройки модуля ведения журнала вы можете использовать различные функции журнала для создания сообщений журнала. Наиболее часто используемые функции журнала — это debug
, info
, warning
, error
и exception
. Каждая функция принимает строковый аргумент, который может быть передан в журнал (опять же, в зависимости от конфигурации).
Функция debug
используется для сообщений отладки, помогающих разработчику при разработке кода, а функция info
предназначена для сообщений, помогающих разработчику понять, как код ведет себя в производственной среде. Функции warning
, error
и exception
используются для регистрации проблем возрастающего уровня серьезности.
Все эти функции принимают необязательный второй аргумент, словарь дополнительной информации, которая будет регистрироваться вместе с сообщением.
Старый против нового при регистрации
В документации модуля ведения журнала говорится, что f-строки менее оптимальны, потому что, как указано в документации по ведению журнала:
Форматирование аргументов сообщения откладывается до тех пор, пока его нельзя будет избежать.
Поэтому для оптимизации модуль предпочитает выполнять оценку зарегистрированных строк как можно позже. Возьмите примеры:
logger.debug("encountered %s", foo) # old style
vs
logger.debug(f"encountered {foo}") # f string
Предположим, что конфигурация ведения журнала выше, чем отладочная (поэтому вызовы debug
не отправляются в журнал). В первой версии окончательная строка не будет вычисляться (поскольку обработчик ведения журнала будет игнорировать вызовы ведения журнала отладки), а во второй версии строка вычисляется немедленно. Как говорят документы:
Возможно, вы захотите избежать этого, если регистратор просто выбросит ваше событие.
Причина, по которой модуль ведения журнала предлагает это, заключается в том, что могут быть случаи, когда оценка строк требует больших ресурсов: возможно, foo
представляет набор запросов с ленивой оценкой ORM, и оценка строки заставит базу данных читать. Было бы обидно, если бы соблюдение кода негативно повлияло на систему. Если ведение журнала снижает производительность приложения, разработчики будут использовать его меньше, а это снизит их производительность как разработчиков.
Улучшите свой код
Code Review Doctor — это инструмент сканирования кода, который предлагает исправления Python и Django прямо в вашем запросе на включение:
Проверьте свои пулл-реквесты GitHub или Bitbucket, сканируйте всю кодовую базу бесплатно онлайн или подпишитесь на нас в Twitter.