В мире программирования, особенно при разработке на Python, часто возникает необходимость не просто выводить статические строки, но и динамически встраивать в них данные, чтобы отобразить информацию пользователю в удобном и понятном виде. Это требует использования специальных методов, которые позволяют форматировать строки таким образом, чтобы они могли включать переменные, результаты вычислений и другие динамические элементы.
Эти методы как раз и называются — форматированием строк.
Форматирование строк — это процесс создания строковых представлений данных, которые могут включать в себя как статический текст, так и динамические элементы, такие как переменные, выражения и другие данные. Цель форматирования строк заключается в обеспечении удобного и понятного способа представления информации, что особенно важно при выводе данных пользователю или при записи их в файлы.
Форматирование строк не только улучшает читаемость и интерпретируемость данных, но и является ключевым аспектом при создании профессиональных и эффективных приложений. В Python, благодаря его гибкости и мощным встроенным функциям, разработчики имеют несколько вариантов для достижения этой цели.
История развития
Форматирование строк в Python прошло через несколько этапов развития, начиная с самых ранних версий языка и до современных реализаций, которые обеспечивают высокую гибкость и удобство использования. Вот краткий обзор ключевых моментов этого развития:
Оператор %
Оператор %
для форматирования строк был доступен с самого начала существования Python, то есть с первой версии языка. Python 1.0, выпущенный в январе 1994 года, уже поддерживал этот оператор. Он был вдохновлен аналогичным оператором в языке C и использовался для вставки значений в строковые шаблоны с помощью плейсхолдеров.
Плейсхолдеры — это места в строке, куда будет выполнена подстановка. Обладающие определенным синтаксисом.
Для форматирования мы можем использовать следующие плейсхолдеры:
Синтаксис |
Определение |
---|---|
%s |
для вставки строк |
%d |
для вставки целых чисел |
%f |
для вставки дробных чисел. Для этого типа также можно определить через точку количество знаков в дробной части |
%e |
выводит число в экспоненциальной записи |
%g |
для автоматического выбора между обычной и экспоненциальной записью. |
%% |
умножает значение на 100 и добавляет знак процента |
%x |
Для представления целочисленных значений в шестнадцатеричном виде |
При вызове метода % в него в качестве аргументов передаются значения, которые вставляются на место плейсхолдеров.
-
Форматирование строк и целых чисел:
name = "Alice" age = 30 print("My name is %s and I am %d years old." % (name, age))
-
Форматирование дробных чисел с указанием точности:
pi = 3.14159 print("The value of pi is approximately %.2f." % pi) # Вывод: The value of pi is approximately 3.14.
-
Форматирование с использованием запятой в качестве разделителя разрядов:
number = 1234567 print("The number is %d and with commas it looks like %d." % (number, number)) # Вывод: The number is 1234567 and with commas it looks like 1234567.
-
Форматирование чисел в экспоненциальной записи:
number = 123456789 print("The number in scientific notation is %e." % number) # Вывод: The number in scientific notation is 1.234568e+08.
-
Форматирование процентов:
percentage = 0.75 print("The percentage is %.2f%%." % (percentage * 100)) # Вывод: The percentage is 75.00%.
Использование словарей для форматирования строк с помощью оператора %
позволяет ссылаться на переменные по именам, что делает процесс форматирования более удобным и упрощает его модификацию в будущем.
Этот подход избавляет от необходимости следить за порядком передаваемых значений, так как каждое значение связывается с соответствующим ключом в словаре. Однако, этот метод требует большего объема кода.
name = "Alice" errno = 0xbadc0ffee print( 'Hello %(name)s, an error with code 0x%(errno)x has occurred!' % { "name": name, "errno": errno } ) # Вывод: 'Hello Alice, an error with code 0xbadc0ffee has occurred!'
Дополнительные параметры форматирования
-
Ширина поля: Можно указать минимальную ширину поля, в котором будет отображаться значение. Например,
%10s
выровняет строку по правому краю в поле шириной 10 символов.
name = "Alice" print("|%10s|" % name) # Вывод: | Alice|
-
Выравнивание: Можно использовать флаги
-
для выравнивания по левому краю и+
для отображения знака числа.
number = 42 print("|%-10d|" % number) # Выравнивание по левому краю print("|%+10d|" % number) # Отображение знака # Вывод: |123456789 | # Вывод: |+123456789|
-
Заполнение нулями: Можно заполнить пустое пространство нулями, используя флаг
0
.
number = 42 print("|%010d|" % number) # Заполнение нулями # Вывод: |0000000042|
Оператор %
для форматирования строк, хотя и был полезен и широко использовался, но имел несколько критичных недостатков:
-
Оператор
%
имел ограниченные возможности для форматирования, особенно в части управления выравниванием, заполнением и другими аспектами. -
Оператор
%
был уязвим для атак, связанных с форматированием строк, таких как инъекция вредоносного кода через непроверенные входные данные. -
Ну и конечно же, оператор
%
был недостаточно гибким.
Все эти недостатки привели к тому, что в 2008 году, был добавлен новый метод для форматирования, который так и назывался — format
. Интересен и тот факт, что он был доступен не только в новой версии Python 3.0, но и в обновлении для старой версии языка (Python 2.6).
Метод format
Данный метод унаследовал все возможности оператора %
и при этом расширил его функционал.
Плюсами данного метода стали:
-
Возможность явного использования именованных и позиционных аргументов.
-
Расширение функциональных возможностей форматирования, например управление выравниванием, заполнением, точностью чисел и разделителем разрядов.
-
Улучшение безопасности и избавление от возможных инъекций.
-
Возможность расширения за счёт переопределения метода
__format__
в пользовательских классах -
Улучшение читаемости благодаря явному указанию аргументов и возможности использования именованных параметров.
Теперь общий синтаксис плейсхолдера выглядит так: {:плейсхолдер}
. Это означает, что плейсхолдеры теперь заключаются в фигурные скобки, а оператор %
был заменен на :
.
В зависимости от плейсхолдера можно добавлять дополнительные параметры. Например, для форматирования чисел float можно использовать следующие параметры
{:[количество_символов][запятая][.число_знаков_в_дробной_части] плейсхолдер}
При вызове метода format в него в качестве аргументов передаются значения, которые вставляются на место плейсхолдеров:
name = "Python" welcome_phrase = "Hello {:s}!" print(welcome_phrase.format(name)) # Вывод: Hello Python!
В качестве результата метод format()
возвращает новую отформатированную строку. Это означает, что мы можем присвоить результат выполнения операции переменной:
your_welcome = welcome_phrase.format(name)
Если форматируемое число больше 999, то мы можем указать в определении плейсхолдера, что мы хотим использовать запятую в качестве разделителя разрядов:
source = "{:,d} символов" print(source.format(5000)) # Вывод: 5,000 символов
Для дробных чисел, то есть таких, которые представляют тип float, перед кодом плейсхолдера после точки можно указать, сколько знаков в дробной части мы хотим вывести:
number = 12.3456789 print("{:.2f}".format(number)) # 12.34 print("{:.3f}".format(number)) # 12.345 print("{:.4f}".format(number)) # 12.3456 print("{:,.2f}".format(12345.12345)) # 12,345.12
Важным нововведением стало и то, что format
стал поддерживать дату и время:
from datetime import datetime now = datetime.now() print("Today is {:%Y-%m-%d}.".format(now)) # Вывод: Today is 2024-07-21.
Несмотря на то, что этот способ обладает всем необходимым функционалом — это не стало пределом. Так 23 декабря 2016 года была выпущена версия Python 3.6 в которой появились…
f-строки
F-строки предоставляют удобный и эффективный способ встраивания выражений Python прямо в строковые литералы, что делает их очень популярным и предпочтительным методом форматирования строк в современном Python.
F-строки обозначаются префиксом f
или F
перед строковым литералом и позволяют включать выражения Python внутри фигурных скобок {}
, которые затем вычисляются и подставляются в строку. Например:
name = "Alice" age = 30 print(f"Hello, {name}! You are {age} years old.") # Вывод: Hello, Alice! You are 30 years old.
А что с плэйсхолдерами?
Благодаря использование синтаксиса фигурных скобок F-строки поддерживают все стандартные спецификаторы форматирования, которые мы рассматривали в предыдущих методах.
Также с помощью специальных символов можно задать длину строки при форматировании:
-
<N: выравнивает строку по левому краю и дополняет ее пробелами с правой стороны до длины N
-
>N: выравнивает строку по правому краю и дополняет ее пробелами с левой стороны до длины N
-
^N: выравнивает строку по центру и дополняет ее пробелами с левой и правой стороны до длины N
-
.N: задает точную длину строки. Если в ней больше N символов, то она усекается
Например, если требуется добавить символы «0» слева (для выравнивания по правому краю), справа (для выравнивания по левому краю) или слева и справа (для выравнивания посередине) от исходной строки до достижения длины в 9 символов:
print(f"{123:0>9}") # Вывод: 000000123 print(f"{123:0<9}") # Вывод: 123000000 print(f"{123:0^9}") # Вывод: 000123000
А теперь мы более подробно рассмотрим возможности и нововведения данного метода форматирования, про которые вы, возможно, не знали:
Небольшие полезности
1) Начиная с Python 3.8, f-строки поддерживают специальный синтаксис для вывода имен переменных вместе с их значениями. Это называется «отладкой» (debugging). Синтаксис выглядит следующим образом:
x = 10 y = 25 print(f"{x = }, {y = }")
2) F-строки позволяют встраивать выражения Python прямо в строковые литералы. Это делает код более компактным и читаемым. Например:
a = 5 b = 10 print(f"The sum of {a} and {b} is {a + b}.") # Вывод: The sum of 5 and 10 is 15.
3) Плюсы есть и в ООП. Так методы __repr__
и __str__
в Python используются для создания строковых представлений объектов. По умолчанию для формирования читаемого строкового представления экземпляров классов используется метод __str__
. Однако, если требуется использовать метод __repr__
вместо __str__
, можно воспользоваться флагом преобразования !r
в f-строках.
Вот пример, демонстрирующий использование этих методов:
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('{self.first_name}', '{self.last_name}')" user = User("Pablo", "Chikoni") print(f"{user}") # Вывод: Pablo Chikoni print(f"{user!r}") # Вывод: User('Pablo', 'Chikoni')
Оптимизированность
Следующим плюсом является и то, что f-строки сильно оптимизированы и работают быстрее, чем другие методы форматирования строк, такие как str.format()
или оператор %
. Это делает их предпочтительным выбором для многих задач, особенно когда требуется высокая производительность.
Постараюсь вам доказать это, следующим примером:
import timeit # Примеры строк для форматирования name = "Alice" age = 30 # Функция для измерения времени выполнения def measure_time(stmt, number=1000000): return timeit.timeit(stmt, number=number, globals=globals()) # Измерение времени выполнения для каждого метода f_string_time = measure_time('f"My name is {name} and I am {age} years old."') format_time = measure_time('"My name is {} and I am {} years old.".format(name, age)') percent_time = measure_time('"My name is %s and I am %d years old." % (name, age)') # Вывод результатов print(f"f-string time: {f_string_time:.6f} seconds") print(f"str.format() time: {format_time:.6f} seconds") print(f"operator % time: {percent_time:.6f} seconds")
выведет:
f-string time: 0.166108 seconds str.format() time: 0.330560 seconds operator % time: 0.276897 seconds
Как вы можете заметить, скорость выполнения отличается почти в 2 раза, от всех предыдущих методов форматирования. Так что следуя Дзен Python, а именно пункту “Должен быть один и только один очевидный способ сделать что-то в Python”. Мы бы рекомендовали вам использовать f-строки.
Если вам понравилась данная статья, то вы можете подписаться на наш телеграмм канал. В нём вы найдёте ещё множество интересных и полезных статьей!
ссылка на оригинал статьи https://habr.com/ru/articles/830282/
Добавить комментарий