Перво-наперво, я знаю, что 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 или более поздней версии.

Надеюсь, эти советы хоть немного облегчат вам жизнь.