F-строки и 3 эффективных способа их применения

Далеко в прошлом остались те времена, когда разработчики Python еще использовали оператор % для форматирования строк. 

С момента появления Python 3.0 его постепенно заменили вызовом метода .format() для строкового объекта.  

А вот когда наступила эра Python 3.6 и последующих версий, то в обиход вошли f-строки, ставшие новым способом вставки выражения Python внутрь строковых констант. И в настоящее время многие уже освоили это нововведение. 

Краткий обзор форматирования строк в Python 

Для тех, кто еще не знаком с этим способом форматирования, отметим, что работать с f-строками чрезвычайно просто. Достаточно лишь предварить строку префиксом f или F, а затем поставить одинарные, двойные или даже тройные кавычки для оформления строки, например f"Hello, Python!"

Наверняка большинство из вас прекрасно осведомлены о механизме форматирования с помощью f-строк, но в этой статье будут представлены малоизвестные способы их применения в Python 3.8+.

Содержание.

  • F-строки для более эффективной отладки. 
  • F-строки для форматирования float до N десятичных знаков, денежных значений, объектов datetime и заполнения целых чисел ведущими нулями или пробелами.
  • F-строки для конверсий (ASCII и repr()). 

Итак, приступаем. 

1. F-строки для отладки 

Разработчики часто задействуют инструкции print для отладки кода просто потому, что их так легко добавлять. 

Как правило, мы делаем так: 

viewer = "🐊"
owner = "🐼"
editor = "🐓"

print(viewer)
print(owner)
print(editor)

Отличный способ запутаться в переменных и их значениях. 

А вот и вывод в терминале: 

🐊
🐼
🐓

На самом деле с инструкциями print в данном коде все в порядке. 

Однако если терминал переполнен другими логами отладчика, то велика вероятность забыть порядок выводимых переменных. В таком случае отладка с помощью print быстро превращается в квест по поиску иголки в стоге сена. Вот как в нашем примере:

🐊 
🐼 -- Извините, а какой переменной принадлежит это значение? 
🐓

Более эффективный способ вывода переменных в процессе отладки 

Для решения этой проблемы воспользуемся print(f’{variable_name=}’):

print(f"{viewer=}")
print(f"{owner=}")
print(f"{editor=}")

# Поток Stdout:

# viewer = "🐊"
# owner = "🐼"
# editor = "🐓"

F-строки делают вывод более понятным!

Даже не смотря на то, что мы должны обернуть переменные синтаксисом f-строк, все становится намного яснее. Теперь уже не перепутаешь порядок выводимых переменных во время отладки. 

Более того, благодаря такому способу применения f-строк сохраняются пробелы. Их пользу в процессе отладки вы сможете оценить, оказавшись в гуще запутанных логов в терминале. 

print(f"{viewer=}")
print(f"{owner=}")
print(f"{editor=}")

# Поток Stdout:

# viewer = "🐊"
# owner = "🐼"
# editor = "🐓"

2. Форматирование строк 

Помимо эффективности f-строк в отладке, большего всего полезна их гибкость, позволяющая легко форматировать строки. 

Благодаря этому свойству становится гораздо проще читать, писать и поддерживать вывод строки по сравнению со старой доброй конкатенацией. 

И сейчас вы в этом убедитесь на простейшем примере переменных типа float

Форматирование float до N десятичных знаков 

Допустим, нужно вывести переменную типа float с двумя десятичными знаками после точки, преобразовав 3.1425123 в 3.14. Не такой уж и редкий случай, надо сказать. 

Как правило, на ум приходят варианты со встроенным методом round или “устаревшим” str.format. Ниже рассмотрим эти способы ограничения числа с плавающей точкой до двух десятичных знаков: 

# "Устаревшие" способы корректировки числа с плавающей точкой до двух десятичных знаков
float_variable = 3.141592653589793

print("%.2f" % float_variable)
print("{:.2f}".format(float_variable))

# Поток Stdout:

# 3.14
# 3.14

А теперь для этой цели попробуем задействовать f-строки:

float_variable = 3.141592653589793

print(f"{float_variable:.2f}")

# Поток Stdout:
# 3.14

По сравнению с str.format() f-строки все значительно упрощают. 

Преобразование float в “красивый” денежный формат 

Когда дело касается денежных единиц, строкам необходимо придать максимально удобный для пользователя вид. Например, целесообразно представить значение 3142671.76 как $3,142,671.76

В данном случае с помощью f-строк очень удобно оформить значение float в денежном формате. С этой целью нам понадобится ,:2f.

money = 3_142_671.76 # 💡 Это тоже самое, что и 3142671.76

print(f"${money:,.2f}")

# Поток Stdout:
# $3,142,671.76

Вот так без особого труда мы представили переменную типа float в “красивом” денежном формате. 

Представление datetime в “красивом" формате посредством strftime 

F-строки можно использовать не только для форматирования переменных типа float, но и типа datetime.

Наиболее распространенный способ представить объект datetime в удобном для восприятия формате, например 05-July-2021, состоит в применении стандартного встроенного метода strftime, а именно datetime_var.strftime(‘%d-%b-%y’).

То же самое мы легко сможем сделать, обратившись к f-строкам:

from datetime import datetime

now = datetime.now()

# Стандартный способ 
formatted_datetime_now = now.strftime('%d-%B-%Y')
print(formatted_datetime_now)

# Способ с f-строкой 
formatted_datetime_now = f"{now:%d-%B-%Y}"
print(formatted_datetime_now)

# Поток Stdout
# 05-July-2021

Заполнение переменных int ведущими нулями или пробелами 

В зависимости от того, над чем вы работаете, бывают ситуации, требующие заполнить ведущими нулями целое число при его отображении или использовании в виде строки. 

Вместо того, чтобы для этой цели писать пользовательскую функцию, мы без особого труда сделаем это с помощью f-строк. Итак, заполняем целочисленную переменную ведущими нулями: 

# Выводим длину в 20 цифр и заполняем остальные позиции нулями. 

int_variable = 1_234_567
print(f'{int_variable:020}')

# Поток Stdout
# 00000000000001234567

# Выводим длину в 24 цифры и заполняем остальные позиции нулями 
int_variable = 30
print(f'{int_variable:024}')

# Поток Stdout
# 000000000000000000000030

Для заполнения целых чисел ведущими пробелами делаем следующее: 

# Выводим длину в 10 символов и заполняем остальные позиции ведущими пробелами 
whitesplace
int_variable = 20_21
print(f'{int_variable:10d}')

# Stdout
# '      2021'

# Выводим длину в 5 символов и заполняем остальные позиции пробелами 
print(f"{int_variable:5d}")

# Поток Stdout
# ' 2021'

Конверсия

В последнем разделе статьи мы кратко рассмотрим несколько примеров с f-строками для конверсии. Если в f-строке присутствует синтаксис восклицательного знака !, за которым следует переменная, то она проведет дополнительное преобразование этой переменной. 

Преобразование строки в ASCII 

Например, можно легко вывести представление строки в ASCII с помощью f’{your_variable!a}’ следующим образом:

owl = '🦉'
print(f'{owl!a}')

# Поток Stdout
# '\U0001f989'

Перед вами эмоджи в виде ASCII. 

A repr() alternative with f-string

И наконец, еще один отличный способ использовать синтаксис ! в f-строках  —  отобразить строку, которая содержит выводимое представление объекта наподобие метода repr() в Python. 

Обратимся к примеру, в котором вместо repr() воспользуемся  !r:

from datetime import datetime

now = datetime.now()

# repr()
print(repr(now))

# F-строки  
print(f'{now!r}')

# Поток Stdout
# datetime.datetime(2021, 7, 5, 13, 2, 34, 672383)

repr(now) == f'{now!r}'
# True

Заключение 

С началом эры Python 3.6 f-строки стали отличным способом форматирования строк. 

Благодаря свойственной им гибкости, позволяющей включать выражения, условия и даже форматирование в строковый объект, f-строки не только просты, но и высокоэффективны. 

Из всех перечисленных способов мне особенно нравится форматирование объекта datetime и любых денежных значений. 

Надеемся, вы почерпнули для себя много интересного из статьи и воспользуетесь данными приемами в своих сторонних проектах или базе кода. 

Читайте также:

Читайте нас в Telegram, VK и Яндекс.Дзен


Перевод статьи Jerry Ng: 3 Useful Python f-string Tricks You Probably Don’t Know

Предыдущая статьяИнтерфейсы с вкладками без JavaScript
Следующая статьяПошаговое руководство по обучению модели на Vertex AI от Google Cloud