Перво-наперво, я знаю, что f-строки не очень популярны в прессе, но я изначально Java-разработчик — мне пришлось переключиться на Python для нового проекта.
Одна из первых проблем, с которыми мне пришлось столкнуться, заключалась в том, как форматировать строки, содержащие переменные. Для тех из вас, кто не знаком с Java, вы делаете это так:
System.out.printf("How long is %s? Well, it's %d %n characters long of course!", "a piece of string", "a piece of string".length()); /* OUTPUT How long is a piece of string? Well, it’s 17 characters long of course! */
Я хотел посмотреть, как вы это делаете, Python, поэтому я просто погуглил «форматирование строк Python».
Когда я ввел свой поиск, большинство лучших результатов поиска описывали старые способы обработки строк в Python (это могло измениться с тех пор, как я написал эту статью).
В любом случае, избранный фрагмент Google по форматированию строк (взято с learnpython.org) сообщил мне, что Python использует форматирование строк в стиле C…
«Отлично», — подумал я, — «я знаю, как это работает» (синтаксис Java не сильно отличается). Итак, мой предыдущий оператор Java будет выглядеть так в Python.
print("How long is %s? Well, it's %s characters long of course!" % ("a piece of string", len("a piece of string"))) # OUTPUT: How long is a piece of string? Well, it's 17 characters long of course!
Это немного проще, чем Java, но все же имеет некоторые связанные с этим сложности. Чтобы объяснить, позвольте мне показать вам более длинный пример. Это генератор историй:
В этом примере делается попытка эмулировать контекстно-свободную грамматику, используя только родное форматирование строк Python. Он был вдохновлен библиотекой Javascript tracery , которая использует контекстно-свободные грамматики для построения предложений из меньших строк. Вы можете использовать Tracery для создания генеративных историй и интерактивных текстовых игр.
Контекстно-свободная грамматика дает нам хороший способ исследовать сложность обработки строки с большим количеством переменных.
Чтобы понять почему, давайте увеличим масштаб этой строки:
print("%s traveled with her pet %s. %s was never %s, for the %s was always too %s." % (protagonist, creature, protagonist, protagonist_mood, creature, creature_mood))
Довольно сложно прочитать заявление и предугадать, как будет выглядеть предложение. Вы должны прыгать туда и обратно между шаблоном предложения и списком переменных, чтобы понять, какой результат вы получите.
Обратите внимание, что мне также пришлось повторить переменные протагониста и существа, потому что замены «%s» разрешаются в соответствии с порядком, в котором перечислены переменные. Оператор %s используется шесть раз, поэтому структура ожидает шесть переменных.
Есть обходные пути для решения этой проблемы, но проще использовать более новое расширенное форматирование строк Python. Этот метод использует фигурные скобки вместо оператора %, и вы больше не ограничены порядком переменных.
С этим новым стилем форматирования наш предыдущий пример будет выглядеть так:
print("{0} traveled with her pet {1}. {0} was never {2}, for the {1} was always too {3}." % (protagonist, creature, protagonist_mood, creature_mood))
Вы можете поместить порядковый номер между фигурными скобками, чтобы указать переменную, которую вы хотите получить. Переменная animal находится на втором месте в списке (технически позиция 1), поэтому мы ссылаемся на нее с помощью {1}. Удобно, это также вторая замена, необходимая в шаблоне предложения.
Но это снова упоминается как пятая замена в конце предложения. Таким образом, мы должны мысленно отделить порядок замен от номеров индексов, на которые они ссылаются (номер замены 5 использует переменную в позиции 1).
Мы сократили количество переменных, но в некотором смысле результат стал даже сложнее предвидеть (по крайней мере, с первого взгляда).
Итак, это момент, к которому я готовился, и, надеюсь, вы понимаете, почему я использовал в качестве примера контекстно-свободные грамматики.
Барабанная дробь, пожалуйста... представляем... фа-струну! (Хорошо, он вышел чуть более трех лет назад, начиная с Python 3.6, но пошутите).
Этот тип примера намного легче понять, когда мы делаем это в стиле f-string!
print(f"{protagonist} traveled with her pet {creature}. {protagonist} was never {protagonist_mood}, for the {creature} was always too {creature_mood}.")
Посмотри на это! Больше не нужно переключаться между шаблоном предложения и списком переменных. Вы просто ссылаетесь на них непосредственно в контексте, где происходит замена.
Конечно, f-строки более мощные, чем этот простой пример, на сайте Real Python есть полезная статья, которая объясняет всю мощь f-строки. Я просто хотел познакомить с f-строками таких людей, как я, которые переходят с другого языка на Python и хотят более эффективного способа работы со строками. Естественно, вы можете найти более подробную информацию в Документации Python.
И вот еще один бонусный совет: предположим, что вы хотите преобразовать существующие проекты, в которых используется более старое форматирование строк, и обновить форматирование, чтобы повсеместно использовать f-строки. Вы делаете это автоматически с помощью модуля flynt, который доступен для Python 3.6 или более поздней версии.
Надеюсь, эти советы хоть немного облегчат вам жизнь.