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) в Москве:



