Вступление
Рано или поздно форматирование строк становится неизбежным злом для
большинства программистов. Тем более, что это было раньше, до эры
графического интерфейса пользователя с толстым клиентом, но
необходимость иметь конкретное строковое представление все еще является
достаточно распространенным вариантом использования. Мое первое
знакомство было еще в колледже, когда у меня был профессор старой школы,
который нечисто любил заставлять нас писать консольные Java-приложения с
невротическими спецификациями для вывода с помощью printf(...)
. Одна
вещь, которая оставалась верной тогда и остается актуальной сейчас, -
это то, что документация по форматированию строк (практически для всех
языков) оставляла желать лучшего. Я надеюсь облегчить эту боль сегодня,
написав о том, как выполнить форматирование строк в Python.
В Python существует несколько методов форматирования строк, если быть точным, четыре. Интересно, что это своего рода противоречие с уклоном в Python о том, что, как правило, должен быть один четкий лучший способ выполнить задачу. Однако, если вы потратили какое-то разумное количество времени на язык, вы, вероятно, видели этот разрозненный набор методов и задавались вопросом: «Что со всем этим делать?».
Выполнение четырех техник форматирования строк
Начнем с наиболее часто встречающегося метода, в котором используется
оператор %
Я говорю «самый распространенный» просто потому, что он
существует дольше всех и вы видите его повсюду (книги, сообщения в
блогах, переполнение стека и т. Д.). Чтобы использовать этот метод, вы
указываете заполнитель в строке, используя %s
для строк и %d
для
чисел.
>>> "Hello reader, welcome to the %s form of string formatting." % 'modulus'
'Hello reader, welcome to the modulus form of string formatting.'
>>>
>>> "Formatting multiple (%d, %d, %d, ...) values requires a %s." % (1, 2, 3, 'tuple')
'Formatting multiple (1, 2, 3, ...) values requires a tuple.'
>>>
>>> print("""If you prefer named placeholders for values %(one)d, %(two)d,
... %(three)d ... you can use a dict""" % {'one':1, 'two':2, 'three':3})
If you prefer named placeholders for values 1, 2,
3 ... you can use a dict
Следующий прием - метод str.format(...)
. Это должно было быть заменой
ранее показанного стиля %
В этом методе используется {}
в фигурных
скобках, чтобы указать, где и как преобразовать значение в строку.
>>> "Hello reader, welcome to the {} form of string formatting".format('str.format(...)')
'Hello reader, welcome to the str.format(...) form of string formatting'
>>>
>>> print("""Formatting multiple ({0}, {1}, {2}, ...) values requires
... that you use multiple {3} brackets and optionally specify ordering
... values.""".format(1,2,3,'{}'))
Formatting multiple (1, 2, 3, ...) values requires
that you use multiple {} brackets and optionally specify ordering
values.
>>>
>>> print("""The {language} str.format() method also allows you to use
... named parameters which help keep code {adjective}
... """.format(language='Python', adjective='concise'))
The Python str.format() method also allows you to use
named parameters which help keep code concise
Затем есть метод строкового шаблона, который представляет собой класс в
строковом модуле . Этот
метод форматирования строк более подробный и не поддерживает
спецификаторы типа (s, d, f и т. Д.), В отличие от двух предыдущих. С
помощью этого метода вы указываете заполнитель в строке, добавляя к
желаемому значению префикс $
в конструкторе класса Template(...)
,
затем вы вызываете substitute(...)
для созданного объекта с
именованным параметром. . Этот метод гораздо менее распространен из-за
его меньшей мощности и гибкости.
>>> from string import Template
>>> tmpl = Template("Hello my name is $name")
>>> tmpl.substitute(name='Adam')
'Hello my name is Adam'
Последний метод и самая последняя реализация, доступная только в Python
3.6, известна как интерполяция
строк . Это имеет
сходство со строкой шаблона Javascript ES6. Строковая интерполяция
требует, чтобы строковый литерал имел префикс f""
и позволяет
указывать как выражения, так и переменные непосредственно внутри строки,
если они заключены в квадратные скобки {}
>>> method="String Interpolation"
>>> f"Hello reader, I am the {method} of formatting"
'Hello reader, I am the String Interpolation of formatting'
>>>
>>> f"With this method you can have expressions like {{1 + 1}} = {1 + 1}"
'With this method you can have expressions like {1 + 1} = 2'
Углубляемся в форматирование строк
В следующих разделах я собираюсь ограничить обсуждение только методом
str.format()
f""
интерполяции, поскольку они являются
предпочтительными методами форматирования строк. Темы, в которые я хотел
бы углубиться, включают:
- Выравнивание текста
- Форматирование чисел
- Преобразование типов
И str.format()
и методы интерполяции используют один и тот же
синтаксис для определения форматирования между {}
которые используют
:
для разделения именованных или порядковых идентификаторов слева и
спецификаций форматирования справа.
Выравнивание текста
Вы можете выровнять значения в пределах указанной длины текста,
используя <
, >
или ^
чтобы указать выравнивание по левому краю,
выравнивание по правому краю или центрирование соответственно. Затем вы
следуете этим символам с желаемой шириной символа.
Python> 2.6:
>>> left_aligned = "Left Align"
>>> center = "Centered"
>>> right_aligned = "Right Align"
>>> "{left_aligned:<15}{center:^10}{right_aligned:>15}".format(
... left_aligned=left_aligned,
... center=center,
... right_aligned=right_aligned)
'Left Align Centered Right Align'
Вы также можете указать порядковые номера, а не ключевые слова.
>>> "{1:<15}{0:^10}{2:>15}".format(center, left_aligned, right_aligned)
'Left Align Centered Right Align'
Или вы можете опустить их, если порядок format(...)
совпадает с
порядком {}
.
>>> "{:<15}{:^10}{:>15}".format(left_aligned, center, right_aligned)
'Left Align Centered Right Align'
Python 3.6:
>>> f"{left_aligned:<15}{center:^10}{right_aligned:>15}"
'Left Align Centered Right Align'
В предыдущих примерах я неявно заполнил оставшееся заполненное пространство пробелами, что является поведением по умолчанию. Однако, если это не то, что вы хотите, вы можете заполнить их чем-то другим, указав символ сразу после двоеточия.
Python> 2.6:
>>> "{:><15}|{:-^10}|{:<>15}".format(left_aligned, center, right_aligned)
'Left Align>>>>>|-Centered-|<<<<Right Align'
Python 3.6:
>>> f"{left_aligned:><15}{center:-^10}{right_aligned:<>15}"
'Left Align>>>>>-Centered-<<<<Right Align'
Числа
Форматирование чисел с плавающей запятой, содержащих десятичные разряды,
в Python - легкая задача. Все, что вам нужно сделать, это поставить
после двоеточия букву f
.
Python> 2.6:
>>> rounded_pi = 3.14
>>> "A rounded representation of Pi {:f}".format(rounded_pi)
'A rounded representation of Pi 3.140000'
Python 3.6:
>>> f"A rounded representation of Pi {rounded_pi:f}"
'A rounded representation of Pi 3.140000'
Обратите внимание, что в строке шесть десятичных знаков. Это связано с тем, что по умолчанию спецификатору float дается шесть мест, которые он либо заполняет нулями, либо округляет, чтобы содержать только шесть, в зависимости от ввода. Например, если я импортирую более длинную константу Пи из математического модуля, вы увидите, как округляется в действии.
Python> 2.6:
>>> from math import pi
>>> pi
3.141592653589793
>>> "A rounded representation of Pi {:f}".format(pi)
'A rounded representation of Pi 3.141593'
Python 3.6:
>>> f"A rounded representation of Pi {pi:f}"
'A rounded representation of Pi 3.141593'
Чтобы указать другую точность (количество десятичных знаков), просто
поставьте перед f
желаемое количество десятичных знаков.
Python> 2.6:
>>> "A rounded representation of Pi {:.3f}".format(pi)
'A rounded representation of Pi 3.142'
Python 3.6:
>>> f"A rounded representation of Pi {pi:.3f}"
'A rounded representation of Pi 3.142'
Другой вариант форматирования чисел с плавающей запятой - спецификатор
процентов. Это работает путем преобразования ожидаемой пропорции или
отношения (0-1) в значение из 100 и обрабатывает оставшуюся десятичную
часть аналогично f
с точностью по умолчанию, равной шести.
Python> 2.6:
>>> receptions = 17
>>> passes = 29
>>> "The completion percentage is {:.2%}".format(receptions/passes)
'The completion percentage is 58.62%'
Python 3.6:
>>> f"The completion percentage is {receptions/passes:.2%}"
'The completion percentage is 58.62%'
Хорошо, так что это касается большинства случаев использования чисел с
плавающей запятой, но как насчет больших чисел? Python также
поддерживает их форматирование с помощью запятых для повышения
удобочитаемости больших чисел. Для того, чтобы воспользоваться этим
просто поместить ,
после двоеточия.
Python> 2.6:
>>> house_price = 299999.99
>>> "The price of the house is ${:,}".format(house_price)
'The price of the house is $299,999.99'
Python 3.6:
>>> f"The price of the house is ${house_price:,}"
'The price of the house is $299,999.99'
Преобразования типов
Преобразование типов - это немного менее распространенный вариант использования, но время от времени они возникают. Основные преобразования типов для чисел следующие:
Преобразование Описание
б Двоичный о Восьмеричный Икс Шестнадцатеричный d Десятичный
Как и другие спецификаторы формата, они работают, добавляя их после двоеточия. Надеюсь, этот общий шаблон синтаксиса форматирования станет вам понятен.
Python> 2.6:
>>> number = 157
>>> print("Binary: {:b}\nOctal {:o}\nHexadecimal: {:x}\nDecimal: {:d}".format(
... number,
... number,
... number,
... number))
Binary: 10011101
Octal 235
Hexadecimal: 9d
Decimal: 157
Python 3.6:
>>> print(f"Binary: {number:b}\nOctal {number:o}\nHexadecimal: {number:x}\nDecimal: {number:d}")
Binary: 10011101
Octal 235
Hexadecimal: 9d
Decimal: 157
Заключение
В этом кратком руководстве по форматированию строк я почти не коснулся поверхности, но надеюсь, что смог привести несколько конкретных примеров распространенных вариантов использования, с которыми вы, вероятно, столкнетесь в своих повседневных программах на Python. Моя цель состояла в том, чтобы дать базовое объяснение синтаксиса форматирования строк и методов реализации. Отсюда у вас должно быть достаточно понимания, чтобы углубиться в детали документации. Спасибо, что прочитали, и не стесняйтесь оставлять комментарии ниже.