F-strings появились в Python 3.6 и стали очень удобным и полезным инструментов для форматированного вывода. Но они обладают некоторыми особенностями, о которых не все знают. Поэтому в этой статье остановимся на них
Форматированный вывод дат и времени
Код курса
DPREP
Ближайшая дата курса
по запросу
Продолжительность
ак.часов
Стоимость обучения
0 руб.
Для нужного представления даты в виде строки согласно шаблону обычно используется функция strftime
(см. тут). Причем есть еще функция strptime
, и их нужно не путать. Но знали ли, что это можно сделать обычным f-strings? Пример кода на Python:
import datetime today = datetime.datetime.today() print(f"{today:%Y-%m-%d}") # 2022-04-05 print(f"{today:%Y}") # 2022
“По-честному” то же самое можно было бы сделать вот так:
print(today.strftime("%Y-%m-%d"))
Узнать, какие шаблоны для даты и времени можно через man-страницу: man strftime
.
Форматированный вывод имен
Начиная с Python 3.8, появилась возможность выводить имена переменных вместе с их значением через f-strings:
x = 10 y = 25 print(f"x = {x}, y = {y}") # x = 10, y = 25 print(f"{x = }, {y = }") # Лучше! (3.8+) # x = 10, y = 25 print(f"{x=}, {y=}") x=10, y=25 print(f"{x = :.3f}") # x = 10.000
Эта особенность называется отладкой (debugging). Она позволяет писать немного меньше кода.
Магические методы __repr__
и __str__
Если вы передадите в функцию print
экземпляр класса, то только узнаете имя класса, которому он принадлежит. Чтобы сделать форматированный вывод более информативным, используются магические методы __repr__
и __str__
. Обычно __repr__
используется для отладочного вывода, а __str__
— для пользовательского. Поэтому чтобы вывести именно результат __repr__
, в f-string добавляется флаг !r
:
class User: def __init__(self, first_name, last_name): self.first_name = first_name self.last_name = last_name def __str__(self): return f"{self.first_name} {self.last_name}" def __repr__(self): return f"User's name is: {self.first_name} {self.last_name}" user = User("John", "Doe") print(f"{user}") # John Doe print(f"{user!r}") # User's name is: John Doe
Производительность
Многие удобные “фишки” и синтаксический сахар могут стоить дорого в плане производительности. Однако это не действует на f-string в Python. Посмотрите на скорость выполнения обычного вывода и с использованием f-string:
# python -m timeit -s 'x, y = "Hello", "World"' 'f"{x} {y}"' from string import Template x, y = "Hello", "World" print(f"{x} {y}") # 39.6 наносек за цикл - Быстро! print(x + " " + y) # 43.5 наносек за цикл print(" ".join((x, y))) # 58.1 наносек за цикл print("%s %s" % (x, y)) # 103 наносек за цикл print("{} {}".format(x, y)) # 141 наносек за цикл print(Template("$x $y").substitute(x=x, y=y)) # 1.24 микросекунд за цикл - Медленно!
Все эти форматированные выводы были оценены с помощью timeit
. И можно увидеть, что f-strings самые быстрые в этом списке. Уже ради скорости их можно использовать в своем коде.
Удобство использования
F-strings поддерживают специальный мини-язык для форматированного вывода, который дает возможность выводить так, как считается нужным.
text = "hello world" # Center text: print(f"{text:^15}") # ' hello world ' number = 1234567890 # Set separator print(f"{number:,}") # 1,234,567,890 number = 123 # Add leading zeros print(f"{number:08}") # 00000123
Вложенные f-strings в Python
Интересно, что f-strings можно вкладывать друг в друга:
number = 254.3463 print(f"{f'${number:.3f}':>10s}") # ' $254.346'
Вложенные f-strings можно использовать еще для переменных в качестве модификаторов:
import decimal width = 8 precision = 3 value = decimal.Decimal("42.12345") print(f"output: {value:{width}.{precision}}") # 'output: 42.1'
Форматированный вывод с условием
Вместе с вложенными f-strings можно добавлять условные конструкции:
import decimal value = decimal.Decimal("42.12345") print(f'Result: {value:{"4.3" if value < 100 else "8.3"}}') # Result: 42.1 value = decimal.Decimal("142.12345") print(f'Result: {value:{"4.2" if value < 100 else "8.3"}}') # Result: 142 x = 10 y = 5 print(f"{f'{x = }' if x > 0 else f'{y = }'}") # x = 10
Хотя читаемость такого кода оставляет желать лучше. Такую конструкцию можно использовать для отладки, а потом поменять на более понятный код.
Форматированный вывод лямбда-выражений
Еще в копилку менее читаемого кода является форматированный вывод лямбда-выражений:
print(f"{(lambda x: x**2)(3)}") # 9
Скобки вокруг лямбда-выражения обязательны, иначе двоеточие будет считаться модификатором.
Код курса
DPREP
Ближайшая дата курса
по запросу
Продолжительность
ак.часов
Стоимость обучения
0 руб.
Еще больше подробностей о особенностях программирования на Python вы узнаете на наших образовательных курсах в лицензированном учебном центре обучения и повышения квалификации руководителей и ИТ-специалистов (менеджеров, архитекторов, инженеров, администраторов, Data Scientist’ов и аналитиков Big Data) в Москве: