Фотография автора

Привет, меня зовут Влад.

Здесь я пишу на темы в которых пытаюсь разобраться: веб-дизайне, программировании, веб-аналитике и рекламе.

Может о чем-то еще.

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

В python существует несколько способов форматирования текста:

  1. Форматирование с помощью f-strings;
  2. Метод .format();
  3. Template Strings;
  4. Устаревший способ форматирования с помощью оператора %. В теории его можно встретить где-то в коде, но я подробнее остановлюсь только на первых двух пунктам.

Предположим, что у нас есть стартап, где пользователи мечтают пополнить свой баланс.

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

class User:
    def __init__(self, first_name):
        self.__first_name = first_name
        self.__balance = 0

    def balance_increase(self, cash):
        self.__balance += cash

    def get_notification_text(self):
        return (f'{self.__first_name}, у тебя на балансе {self.__balance} руб.'
                ' Скорее потрать их!')

vlad = User('Влад')
vlad.balance_increase(100000)

print(vlad.get_notification_text())
# Влад, у тебя на балансе 100000 руб. Скорее потрать их!

Выше, в методе get_notification_text() используются f-строки. В фигурных скобках указываются переменные, значение которых мы хотим передать. Если убрать фигурные скобки, то просто будет выведен текст: «self.__first_name, у тебя на балансе self.__balance руб. Скорее потрать их!»

В f-строках также можно использовать условные выражения, приводить дату или числа к нужному формату.

Форматирование с помощью метода .format()

В примере из предыдущего пункта можно было бы использовать и метод .format вместо эф-строк.
Но выглядит это чуть сложнее для понимания, особенно если бы переменных было больше.

class User:
    def __init__(self, first_name):
        self.__first_name = first_name
        self.__balance = 0

    def balance_increase(self, cash):
        self.__balance += cash

    def get_notification_text(self):
        return ('{name}, у тебя на балансе {balance} руб.'
                ' Скорее потрать их!').format(name=self.__first_name,
                                              balance=self.__balance)

vlad = User('Влад')
vlad.balance_increase(100000)

print(vlad.get_notification_text())
# Влад, у тебя на балансе 100000 руб. Скорее потрать их!

Выше использовать именованные аргументы, но можно сделать и через позиционные:

    def get_notification_text(self):
        return ('{}, у тебя на балансе {} руб.'
                ' Скорее потрать их!').format(self.__first_name,
                                              self.__balance)

Результат будет идентичным, как и в других примерах: «Влад, у тебя на балансе 100000 руб. Скорее потрать их!».

Есть еще такой вариант:

    def get_notification_text(self):
        return ('{1}, у тебя на балансе {0} руб.'
                ' Скорее потрать их!').format(self.__balance,
                                              self.__first_name)

Здесь мы вместо пустых скобок или названия аргумента передаём его позицию. В данном случае я специально начал с последнего аргумента, чтобы было чуть очевиднее что происходит. Сначала подставляется значение переменной first_name, а затем значение balance.

F-strings

F-string расшифровывается как «formatted string literal» и представляет из себя быстрый и функциональный способ форматирования строк и что не менее важно — легко читаемый.

Давайте сравним:

import datetime as dt

birth_date = dt.date(1992, 10, 3)
current_date = dt.date.today()

message = 'Привет! Я родился {birth_date:%d.%m.%Y}.'.format(
    birth_date=birth_date
)
print(message)
# Привет! Я родился 03.10.1992.

message = f'Привет! Я родился {birth_date:%d.%m.%Y}.'
print(message)
# Привет! Я родился 03.10.1992.

Как можно заметить из примера — в обоих случаях выводится одно и то же, но формат эф-строк выглядит чище и выполняются они быстрее, но это, конечно же, будет заметно на гораздо больших объемах. Поэтому в первую очередь интересует на сколько просто читать и писать код с f-strings. В данном случае нам не пришлом три раза прописывать переменную birth_date.

Очень важное отличие эф-строк от метода format в том, что f-string это выражение, которое выполняется.

Поэтому нельзя сначала написать шаблон, а затем определить переменные, которые используются в шаблоне, т.к. на момент выполнения выражения (f-string) все переменные уже должны существовать. Поэтому в некоторых случаях будет удобнее использовать метод .format().

Форматирование даты, времени и чисел

Дальнейшие примеры я сделаю с использованием f-строк, но всё это возможно и в методе .format().

С помощью форматирования строк можно влиять и на то как отображаются числа или, например, даты.

a = 1
b = 3

print(f'Если поделить a на b, то получим число: {a / b}')
# Если поделить a на b, то получим число: 0.3333333333333333

print(f'Если поделить a на b, то получим число: {a / b:.2f}')
# Если поделить a на b, то получим число: 0.33

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

С датами тоже всё просто и красиво:

from datetime import datetime as dt

today = dt.today()

print(f'Пишу я эту статью, а за окном {today:%d.%m.%Y}.'
      f' И время на часах {today:%H:%M}.')

# Пишу я эту статью, а за окном 22.06.2023. И время на часах 22:06.

Итог

F-string более удобны в большинстве случаев, у них простой и понятный синтаксис, не нужно держать в голове где и в каком месте стоит переменная, не нужно дополнительно что-либо импортировать и не нужно дублировать по многу раз одни и те же названия переменных.

Более подробно со способами форматирования и эф-строками можно ознакомиться по ссылкам:

  1. https://docs.python.org/3/library/string.html
  2. https://docs.python.org/3/reference/lexical_analysis.html
  3. https://habr.com/ru/companies/wunderfund/articles/674866/
  4. https://pyneng.readthedocs.io/ru/latest/book/08_useful_basics/f-string.html