sonyps4.ru

Python форматированный вывод строк. Комментарии в Python; Форматирование строк: Операторы форматирования и метод format()

До сих пор мы использовали два способа вывода: вывод значений выражений в интерактивном режиме и с помощью инструкции print (третий способ — метод объектов-файлов write() ).

Часто возникает желание иметь больший контроль над форматированием вывода, чем просто выводить значения, разделённые пробелом. Конечно, Вы можете сами обрабатывать строки: с помощью операций среза и объединения можно создать любое расположение, какое только Вы сможете представить. Строки имеют методы, позволяющие дополнять их пробелами до необходимой ширины колонки 1 . Другой путь — использовать оператор % со строкой в качестве левого аргумента. Оператор % интерпретирует строку справа как строку формата в стиле функции sprintf() в C, которую нужно применить к правому аргументу, и возвращает строку с результатом форматирования.

Безусловно, остаётся еще один вопрос: как получить строковое представление для значений различного типа? К счастью, Python предоставляет возможность преобразовывать значение любого типа в строку: с помощью функции str() . Фактически язык предоставляет две функции для получения строкового представления — repr() (тот же эффект можно получить просто заключив выражение в обратные кавычки: `expr` ) и str() . Первый способ, например, используется интерпретатором для вывода значений выражений в интерактивном режиме, второй — для вывода аргументов инструкцией print . Функция str() по возможности возвращает представление, наиболее пригодное для вывода, а функция repr() — для ввода выражения в интерактивном режиме. Приведём несколько примеров:

>>> x = 10 * 3.14

Число 31.4 не может быть точно представлено в двоичном виде, поэтому:

>>> x
31.400000000000002

Однако функция str() выведет число с разумной точностью:

>>> y = 200*200
>>> s = "Значение x равно " + str(x) + \
... ", значение y равно " + str(y) + "..."
>>> print s
Значение x равно 31.4, значение y равно 40000...

Длинные целые числа записываются в языке Python с суффиксом "L". Начиная с версии 1.6, функция str() его не выводит:

>>> repr(1000L)
"1000L"
>>> str(1000L)
"1000"

Строковое представление можно получить и для других типов:

>>> p =
>>> ps = repr(p)
>>> ps
""
>>> `x, y, ("spam", "eggs")`
"(31.400000000000002, 40000, ("spam", "eggs"))"

Функция repr() (или `` ) добавляет кавычки и записывает спецсимволы с помощью управляющих последовательностей:

>>> hello = "hello, world\n"
>>> print hello
hello, world

>>> hellos = `hello`
>>> print hellos
"hello, world\n"

Выведем таблицу квадратов и кубов двумя описанными способами:

>>> for x in range(1, 11):
... print str(x).rjust(2), str(x*x).rjust(3),
... # Обратим внимание на завершающую запятую
... print str(x*x*x).rjust(4)
...
1 1 1
2 4 8
3 9 27
4 16 64
5 25 125
6 36 216
7 49 343
8 64 512
9 81 729
10 100 1000

>>> for x in range(1,11):
... print "%2d %3d %4d" % (x, x*x, x*x*x)
...
1 1 1
2 4 8
3 9 27
4 16 64
5 25 125
6 36 216
7 49 343
8 64 512
9 81 729
10 100 1000

(Обратите внимание на то, что один пробел между колонками был добавлен инструкцией print .)

Этот пример демонстрирует использование метода строк rjust() , который выравнивает строку вправо в поле заданной ширины, дополняя её слева пробелами. Аналогично действуют методы ljust() и center() . Они не выводят ничего — просто возвращают новую строку. Если исходная строка слишком длинная, она не обрезается, а возвращается в неизменном виде: обычно лучше внести беспорядок в расположение колонок, чем вывести неверное значение. (Если Вы действительно хотите её обрезать, воспользуйтесь операцией среза: "s.ljust(n)" .)

Также может быть полезна функция zfill() , определённая в модуле string , которая дополняет слева нулями строку с числом, корректно обрабатывая знаки плюс и минус:

>>> import string
>>> string.zfill("12", 5)
"00012"
>>> string.zfill("-3.14", 7)
"-003.14"
>>> string.zfill("3.14159265359", 5)
"3.14159265359"

Использование оператора % выглядит примерно так:

>>> import math
>>> print "Значение PI приблежённо равно %5.3f." % \
... math.pi
Значение PI приблежённо равно 3.142.

Если в строке нужно вывести несколько значений, в качестве правого операнда используется кортеж:

>>> table = {"Sjoerd": 4127, "Jack" : 4098, "Dcab" : 7678}
>>> for name, phone in table.items():
... print "%-10s ==> %10d" % (name, phone)
...
Dcab ==> 7678
Jack ==> 4098
Sjoerd ==> 4127

Большинство форматов работают точно так же, как и в C. Однако, если типы аргументов не соответствуют формату, интерпретатор приводит их к необходимому типу (например, выражение любого типа может быть преобразовано в строку с помощью встроенной функции str() ) или, если это невозможно, генерирует исключение 2 . Вы можете использовать * для того, чтобы передать отдельным параметром ширину поля или точность.

Заметим, что если правый аргумент кортеж, он всегда считается списком аргументов:

>>> def f(x):
... print "Функции передано значение "%s"" % x
...
>>> f(1)

>>> f()

>>> # интерпретируется не так, как вы ожидали
... f((1,))
Функции передано значение "1"
>>> # ошибка
... f((1, 2))
Traceback (most recent call last):
File "", line 2, in
File "", line 2, in f
TypeError: not all arguments converted during string formatting

В данном случае надёжнее будет использовать в качестве правого операнда кортеж, состоящий из одного элемента:

>>> def f(x):
... print "Функции передано значение "%s"" % (x,)
...
>>> # Теперь всё правильно
... f((1,))
Функции передано значение "(1,)"
>>> f((1, 2))
Функции передано значение "(1, 2)"
>>> f(1)
Функции передано значение "1"
>>> f()
Функции передано значение ""

В случае длинных строк формата, Вы можете захотеть ссылаться на переменные по имени вместо их положения. Это можно сделать, используя расширенную запись в виде %(name)format , например:

>>> table = {"Sjoerd": 4127, "Jack": 4098, "Dcab": 8637678}
>>> print "Jack: %(Jack)d; Sjoerd: %(Sjoerd)d; Dcab: %(Dcab)d" % table
Jack: 4098; Sjoerd: 4127; Dcab: 8637678

Такая запись особенно полезна в комбинации со встроенной функцией vars() , которая возвращает словарь с переменными в текущей области видимости.

  • Перевод

Предлагаю вниманию читателей хабры и поклонникам python перевод довольно объемной статьи о форматировании строк. Сказка будет правдивой и намек в ней будет на то, что консерваторам стоит иногда рассматривать что-то новое, даже если привычка упорно сопротивляется.

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

Жду замечания по ошибкам в оформлении и опечаткам в личку - с меня традиционные хабраплюшки.

Я уже много лет пишу на python. Но в самом начале этого пути мне было интересно узнать как форматировать строки в стиле Perl. Напомню, что Perl (и многие интерпретаторы командной строки в Unix) поддерживают два типа строковых литералов - с одинарными кавычками (когда строка выводится как есть), и двойными где на место переменных подставляются их значения. В Perl, например, можно написать что то вроде:

$name = "Reuven"; print "Hello, $name\n";
И программа, соответственно, напишет «Hello, Reuven».

Строковые литералы в python не зависят от типа кавычек и переменные в них никогда не разворачиваются в свои значения. Чтобы этого добиться традиционно использовался оператор % для строк. В этом контексте оператор смотрит на строку слева от себя и подсчитывает сколько значений нужно заменить на значения соответствующих переменных справа от себя. Результатом операции является новая строка со вставленными на место плейсхолдеров значениями переменных. Например:

>>> name = "Reuven" >>> "Hello, %s" % name "Hello, Reuven"
Этот код на python вполне себе работает и выводит персонализированное приветствие. Так, несмотря на мою многолетнюю практику с python - я был вполне удовлетворен применением этого синтаксиса. Да, он не очень приятный и нет, я никогда не держал в памяти гору модификаторов printf, которые влияют на форматирование. В смысле я всегда использовал модификатор "s" (выводить как строку) и мне было достаточно того, что python неявно приводил аргументы к строке.

Но в данный момент факт, что синтаксис % подлежит списанию или, по крайней мере, объявлен устаревшим. В списке рассылки python-dev есть замечание, что в ветке 2.x он проживет минимум до 2022 года, но ничего не сказано про ветку 3.x, так что поддержка этого синтаксиса будет скоро удалена и применять его нежелательно. На смену ему пришел метод str.format.

В своих уроках по python я всегда упоминал о str.format, но в конкретных примерах чаще все полагался все-таки на %. Я даже рекомендовал студентам использовать % так как лично мне он казался намного проще.

Но стойкое ощущение того, что, я делаю что-то не так и, возможно, даже ввожу в заблуждение своих студентов подвигло меня поближе изучить str.format. В ходе исследования, я пришел к следующим выводам: 1) Он ничуть не сложнее % и даже проще в некоторых вариантах применения; 2) Я никогда не применял возможности str.format в полной мере, а они очень удобные, несмотря на некоторое время необходимое для их изучения.

Начнем с простейшего. Скажем кому-нибудь «Good morning», причем обратимся по имени и фамилии, предполагая что они сохранены в переменных «first» и «last». По-старому мы сделали бы так:

>>> first = "Reuven" >>> last = "Lerner" >>> "Good morning, %s %s" % (first, last) "Good morning, Reuven Lerner"
Даже в таком примере мы сталкиваемся с одной из проблем %-синтаксиса - у нас теперь две переменных, и чтобы использовать их обе нам нужно сделать из них кортеж. С точки зрения python это логично, но, уверяю вас, очень многих студентов это очень удивляет.

Как этот пример будет выглядеть в случае str.format? Довольно похоже:

>>> "Good morning, {} {}".format(first, last) "Good morning, Reuven Lerner"
Прошу обратить внимание, что мы немного поменяли принцип. Теперь это не бинарный оператор над строками, а метод объекта строка, принимающий ряд параметров. Это логично и более консистентно. Для тех же студентов оператор % в моих примерах выглядел как дополнение к print, а не операция над строками. Нотация с ".format" после строки делает более очевидным факт того, что это метод относящийся именно к этой строке.

Как вы уже наверняка знаете, вхождения “{} {}” в строке говорят что str.format должен принимать два параметра, значения которых будут вставлены в строку в том порядке, в котором они будут переданы в метод. Аргумента два, поэтому в строке должно быть два вхождения {}. Это немного сложнее понять, так как фигурные скобочки в Python намекают людям на словари и пустые скобочки выглядят не очень приятно. Но это ладно, я вполне могу с этим жить и принял это достаточно легко.

Момент, в котором str.format показывает первое преимущество над % - это при необходимости использования параметров в обратном порядке. На самом деле, с %s этого вообще никак не достичь. Невозможно также использовать значение одной переменной несколько раз. При использовании str.format мы вполне можем поменять последовательность подстановки:

>>> "Good morning, {1} {0}".format(first, last) "Good morning, Lerner Reuven"
Обратите внимание, что если бы я использовал пустые скобочки “{} {}”, то подстановка произошла бы в том же порядке, в каком передаются в метод параметры. Можно представить себе параметры как индексируемую с нуля последовательность и если я хочу поменять порядок следования, то просто проставляю в фигурных скобочках нужные индексы этой последовательности. Самый первый наш пример с str.format можно записать и так:

>>> "Good morning, {0} {1}".format(first, last) "Good morning, Reuven Lerner"
Заметим, что явно указав индексы, мы уже не можем положиться на автоматическую индексацию.

Разумеется, можно использовать последовательность и из списка, воспользовавшись оператором *:

>>> names = ("Reuven", "Lerner") >>> "Good morning, {} {}".format(*names) "Good morning, Reuven Lerner"
Можно использовать и именованные аргументы:

>>> "Good morning, {first} {last}".format(first="Reuven", last="Lerner") "Good morning, Reuven Lerner"
Этот вариант мне особенно нравится. Именованные параметры более явные (если у них хорошие имена), и применение {first} и {last} достаточно читабельно - особенно в сравнении с %(first)s, которое необходимо с оператором %

Именованные параметры можно, также, развернуть из словаря, используя оператор **:

>>> person = {"first":"Reuven", "last":"Lerner"} >>> "Good morning, {first} {last}".format(**person) "Good morning, Reuven Lerner"
Я описал все это своим студентам и был достаточно удивлен тем насколько комфортнее им живется с таким синтаксисом. Да и самому стало приятнее работать.

Нужно упомянуть, что именованные и позиционные аргументы технически можно использовать совместно. Но лучше этого не делать:

>>> person = {"first":"Reuven", "last":"Lerner"} >>> "Good {0}, {first} {last}".format("morning", **person) "Good morning, Reuven Lerner"

Я предупредил.

Чего может не хватать в str.format, так это… гм… форматирования. Плохая новость - в str.format совершенно другие правила определения того как форматировать вывод. Хорошая новость - эти правила достаточно несложно изучить и понять.

Снова начнем с простого: если нужно вывести строку заданной длины, то после имени переменной добавляем двоеточие (:) и затем количество символов. Так, чтобы вывести мое имя и дополнить его до десяти символов пробелами я должен делать так:

>>> "Your name is {name:10}".format(name="Reuven") "Your name is Reuven "
(Обратите внимание что строка дополнена пробелами после имени.)

Если нужно задать выравнивание по правой стороне блока - используется знак > между: и числом:

>>> "Your name is {name:>10}".format(name="Reuven") "Your name is Reuven"
И да, можно явно указать что я хочу выравнивания по левой стороне с помощью знака <
Если нужно вывести значение в центре блока, то вместо < и > используется символ ^:

>>> "Your name is {name:*^10}".format(name="Reuven") "Your name is **Reuven**"
С текстом более менее понятно, но что насчет чисел? Лично мне было трудно предположить как это будет работать, но все оказалось достаточно прямолинейно. Для простого вывода чисел используем синтаксис похожий на строки:

>>> "The price is ${number}.".format(number=123) "The price is $123."
Но для чисел применяется большее количество модификаторов, чем для строк. Например, чтобы вывести число в двоичном виде добавляем модификатор «b», если в шестнадцатеричном - модификатор «x»:

>>> "The price is ${number:b}.".format(number=5) "The price is $101." >>> "The price is ${number:x}.".format(number=123) "The price is $7b."
Разумеется, запись числа можно дополнить лидирующими нулями:

>>> "Your call is important to us. You are call #{number:05}.".format(number=123) "Your call is important to us. You are call #00123."
Заметим, что внутри {} нельзя использовать исполняемый python-код - вместо этого предлагается простенький микроязык отдельный и отличающийся от python в целом. Есть и небольшие исключения. Во-первых можно получить значения атрибутов/свойств через точку, во-вторых получить значение объекта по индексу, используя .

Например:

>>> class Foo(object): def __init__(self): self.x = 100 >>> f = Foo() >>> "Your number is {o.x}".format(o=f) "Your number is 100"n
Мы получили атрибут «х» объекта «f». Этот объект доступен по имени «o» внутри строки. Получить атрибут можно, а вот выполнить его - нет:

>>> "Your name is {name.upper()}".format(name="Reuven") AttributeError: "str" object has no attribute "upper()"
Я пытался выполнить “name.upper()”, предполагая, что будет вызван соответствующий метод, но python не разрешает выполнять код в этом месте и расценивает «upper()» как атрибут вместе со скобками. Без скобок вы получите просто строковое представление функции/метода:

>>> "Your name is {name.upper}".format(name="Reuven") "Your name is "
С помощью квадратных скобок можно взять элемент итерируемого объекта (списка, строки) по индексу. Но операции разрезания (slice) не поддерживаются:

>>> "Your favorite number is {n}.".format(n=numbers) "Your favorite number is 3."
Но:

>>> "Your favorite numbers are {n}.".format(n=numbers) ValueError: Missing "]" in format string
Можно использовать и для получения записей в словаре по имени, но имя вводится без кавычек:

>>> person = {"first":"Reuven", "last":"Lerner"} >>> "Your name is {p}.".format(p=person) "Your name is Reuven."
При попытке использовать кавычки получим исключение…

>>> "Your name is {p["first"]}.".format(p=person) KeyError: ""first""
Здесь приведены не все варианты использования str.format - на деле для каждого типа есть спецификация правил форматирования. Например, опция точности для чисел с плавающей запятой недоступна для строк.

Можно даже добавить собственные правила форматирования для объектов ваших классов так, что у них будет особый способ вывода и модификаторы для его настройки.

Если есть желание изучить эту тему подробнее - стоит начать с PEP 3101, где описан str.format. Могу, также, порекомендовать презентацию Эрика Смита с достаточно хорошим саммари по этой теме. Есть и хорошие примеры о том как перейти от использования % к str.format в документации python

Надеюсь, вам понравилось!

  • Перевод

Предлагаю вниманию читателей хабры и поклонникам python перевод довольно объемной статьи о форматировании строк. Сказка будет правдивой и намек в ней будет на то, что консерваторам стоит иногда рассматривать что-то новое, даже если привычка упорно сопротивляется.

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

Жду замечания по ошибкам в оформлении и опечаткам в личку - с меня традиционные хабраплюшки.

Я уже много лет пишу на python. Но в самом начале этого пути мне было интересно узнать как форматировать строки в стиле Perl. Напомню, что Perl (и многие интерпретаторы командной строки в Unix) поддерживают два типа строковых литералов - с одинарными кавычками (когда строка выводится как есть), и двойными где на место переменных подставляются их значения. В Perl, например, можно написать что то вроде:

$name = "Reuven"; print "Hello, $name\n";
И программа, соответственно, напишет «Hello, Reuven».

Строковые литералы в python не зависят от типа кавычек и переменные в них никогда не разворачиваются в свои значения. Чтобы этого добиться традиционно использовался оператор % для строк. В этом контексте оператор смотрит на строку слева от себя и подсчитывает сколько значений нужно заменить на значения соответствующих переменных справа от себя. Результатом операции является новая строка со вставленными на место плейсхолдеров значениями переменных. Например:

>>> name = "Reuven" >>> "Hello, %s" % name "Hello, Reuven"
Этот код на python вполне себе работает и выводит персонализированное приветствие. Так, несмотря на мою многолетнюю практику с python - я был вполне удовлетворен применением этого синтаксиса. Да, он не очень приятный и нет, я никогда не держал в памяти гору модификаторов printf, которые влияют на форматирование. В смысле я всегда использовал модификатор "s" (выводить как строку) и мне было достаточно того, что python неявно приводил аргументы к строке.

Но в данный момент факт, что синтаксис % подлежит списанию или, по крайней мере, объявлен устаревшим. В списке рассылки python-dev есть замечание, что в ветке 2.x он проживет минимум до 2022 года, но ничего не сказано про ветку 3.x, так что поддержка этого синтаксиса будет скоро удалена и применять его нежелательно. На смену ему пришел метод str.format.

В своих уроках по python я всегда упоминал о str.format, но в конкретных примерах чаще все полагался все-таки на %. Я даже рекомендовал студентам использовать % так как лично мне он казался намного проще.

Но стойкое ощущение того, что, я делаю что-то не так и, возможно, даже ввожу в заблуждение своих студентов подвигло меня поближе изучить str.format. В ходе исследования, я пришел к следующим выводам: 1) Он ничуть не сложнее % и даже проще в некоторых вариантах применения; 2) Я никогда не применял возможности str.format в полной мере, а они очень удобные, несмотря на некоторое время необходимое для их изучения.

Начнем с простейшего. Скажем кому-нибудь «Good morning», причем обратимся по имени и фамилии, предполагая что они сохранены в переменных «first» и «last». По-старому мы сделали бы так:

>>> first = "Reuven" >>> last = "Lerner" >>> "Good morning, %s %s" % (first, last) "Good morning, Reuven Lerner"
Даже в таком примере мы сталкиваемся с одной из проблем %-синтаксиса - у нас теперь две переменных, и чтобы использовать их обе нам нужно сделать из них кортеж. С точки зрения python это логично, но, уверяю вас, очень многих студентов это очень удивляет.

Как этот пример будет выглядеть в случае str.format? Довольно похоже:

>>> "Good morning, {} {}".format(first, last) "Good morning, Reuven Lerner"
Прошу обратить внимание, что мы немного поменяли принцип. Теперь это не бинарный оператор над строками, а метод объекта строка, принимающий ряд параметров. Это логично и более консистентно. Для тех же студентов оператор % в моих примерах выглядел как дополнение к print, а не операция над строками. Нотация с ".format" после строки делает более очевидным факт того, что это метод относящийся именно к этой строке.

Как вы уже наверняка знаете, вхождения “{} {}” в строке говорят что str.format должен принимать два параметра, значения которых будут вставлены в строку в том порядке, в котором они будут переданы в метод. Аргумента два, поэтому в строке должно быть два вхождения {}. Это немного сложнее понять, так как фигурные скобочки в Python намекают людям на словари и пустые скобочки выглядят не очень приятно. Но это ладно, я вполне могу с этим жить и принял это достаточно легко.

Момент, в котором str.format показывает первое преимущество над % - это при необходимости использования параметров в обратном порядке. На самом деле, с %s этого вообще никак не достичь. Невозможно также использовать значение одной переменной несколько раз. При использовании str.format мы вполне можем поменять последовательность подстановки:

>>> "Good morning, {1} {0}".format(first, last) "Good morning, Lerner Reuven"
Обратите внимание, что если бы я использовал пустые скобочки “{} {}”, то подстановка произошла бы в том же порядке, в каком передаются в метод параметры. Можно представить себе параметры как индексируемую с нуля последовательность и если я хочу поменять порядок следования, то просто проставляю в фигурных скобочках нужные индексы этой последовательности. Самый первый наш пример с str.format можно записать и так:

>>> "Good morning, {0} {1}".format(first, last) "Good morning, Reuven Lerner"
Заметим, что явно указав индексы, мы уже не можем положиться на автоматическую индексацию.

Разумеется, можно использовать последовательность и из списка, воспользовавшись оператором *:

>>> names = ("Reuven", "Lerner") >>> "Good morning, {} {}".format(*names) "Good morning, Reuven Lerner"
Можно использовать и именованные аргументы:

>>> "Good morning, {first} {last}".format(first="Reuven", last="Lerner") "Good morning, Reuven Lerner"
Этот вариант мне особенно нравится. Именованные параметры более явные (если у них хорошие имена), и применение {first} и {last} достаточно читабельно - особенно в сравнении с %(first)s, которое необходимо с оператором %

Именованные параметры можно, также, развернуть из словаря, используя оператор **:

>>> person = {"first":"Reuven", "last":"Lerner"} >>> "Good morning, {first} {last}".format(**person) "Good morning, Reuven Lerner"
Я описал все это своим студентам и был достаточно удивлен тем насколько комфортнее им живется с таким синтаксисом. Да и самому стало приятнее работать.

Нужно упомянуть, что именованные и позиционные аргументы технически можно использовать совместно. Но лучше этого не делать:

>>> person = {"first":"Reuven", "last":"Lerner"} >>> "Good {0}, {first} {last}".format("morning", **person) "Good morning, Reuven Lerner"

Я предупредил.

Чего может не хватать в str.format, так это… гм… форматирования. Плохая новость - в str.format совершенно другие правила определения того как форматировать вывод. Хорошая новость - эти правила достаточно несложно изучить и понять.

Снова начнем с простого: если нужно вывести строку заданной длины, то после имени переменной добавляем двоеточие (:) и затем количество символов. Так, чтобы вывести мое имя и дополнить его до десяти символов пробелами я должен делать так:

>>> "Your name is {name:10}".format(name="Reuven") "Your name is Reuven "
(Обратите внимание что строка дополнена пробелами после имени.)

Если нужно задать выравнивание по правой стороне блока - используется знак > между: и числом:

>>> "Your name is {name:>10}".format(name="Reuven") "Your name is Reuven"
И да, можно явно указать что я хочу выравнивания по левой стороне с помощью знака <
Если нужно вывести значение в центре блока, то вместо < и > используется символ ^:

>>> "Your name is {name:*^10}".format(name="Reuven") "Your name is **Reuven**"
С текстом более менее понятно, но что насчет чисел? Лично мне было трудно предположить как это будет работать, но все оказалось достаточно прямолинейно. Для простого вывода чисел используем синтаксис похожий на строки:

>>> "The price is ${number}.".format(number=123) "The price is $123."
Но для чисел применяется большее количество модификаторов, чем для строк. Например, чтобы вывести число в двоичном виде добавляем модификатор «b», если в шестнадцатеричном - модификатор «x»:

>>> "The price is ${number:b}.".format(number=5) "The price is $101." >>> "The price is ${number:x}.".format(number=123) "The price is $7b."
Разумеется, запись числа можно дополнить лидирующими нулями:

>>> "Your call is important to us. You are call #{number:05}.".format(number=123) "Your call is important to us. You are call #00123."
Заметим, что внутри {} нельзя использовать исполняемый python-код - вместо этого предлагается простенький микроязык отдельный и отличающийся от python в целом. Есть и небольшие исключения. Во-первых можно получить значения атрибутов/свойств через точку, во-вторых получить значение объекта по индексу, используя .

Например:

>>> class Foo(object): def __init__(self): self.x = 100 >>> f = Foo() >>> "Your number is {o.x}".format(o=f) "Your number is 100"n
Мы получили атрибут «х» объекта «f». Этот объект доступен по имени «o» внутри строки. Получить атрибут можно, а вот выполнить его - нет:

>>> "Your name is {name.upper()}".format(name="Reuven") AttributeError: "str" object has no attribute "upper()"
Я пытался выполнить “name.upper()”, предполагая, что будет вызван соответствующий метод, но python не разрешает выполнять код в этом месте и расценивает «upper()» как атрибут вместе со скобками. Без скобок вы получите просто строковое представление функции/метода:

>>> "Your name is {name.upper}".format(name="Reuven") "Your name is "
С помощью квадратных скобок можно взять элемент итерируемого объекта (списка, строки) по индексу. Но операции разрезания (slice) не поддерживаются:

>>> "Your favorite number is {n}.".format(n=numbers) "Your favorite number is 3."
Но:

>>> "Your favorite numbers are {n}.".format(n=numbers) ValueError: Missing "]" in format string
Можно использовать и для получения записей в словаре по имени, но имя вводится без кавычек:

>>> person = {"first":"Reuven", "last":"Lerner"} >>> "Your name is {p}.".format(p=person) "Your name is Reuven."
При попытке использовать кавычки получим исключение…

>>> "Your name is {p["first"]}.".format(p=person) KeyError: ""first""
Здесь приведены не все варианты использования str.format - на деле для каждого типа есть спецификация правил форматирования. Например, опция точности для чисел с плавающей запятой недоступна для строк.

Можно даже добавить собственные правила форматирования для объектов ваших классов так, что у них будет особый способ вывода и модификаторы для его настройки.

Если есть желание изучить эту тему подробнее - стоит начать с PEP 3101, где описан str.format. Могу, также, порекомендовать презентацию Эрика Смита с достаточно хорошим саммари по этой теме. Есть и хорошие примеры о том как перейти от использования % к str.format в документации python

Надеюсь, вам понравилось!

Метод строк str.format() позволяет выполнять подстановку переменных, форматировать значения и объединять элементы в одну строку посредством позиционного форматирования, вследствие чего код программы становится более читабельным и удобным.

Данное руководство охватывает основные методы форматирования строк в Python.

Метод format

Метод форматирования str.format() добавляют в строку один или несколько заполнителей, которые определяются фигурными скобками ({}). Вы можете передать методу любое значение, которое необходимо вставить в строку. При запуске программы это значение будет добавлено в строку в то место, где находятся фигурные скобки.

Например:

print("I have {} apples.".format(5))
I have 5 apples.

В приведённой выше строке используются фигурные скобки:

"I have {} apples."

Метод str.format() имеет значение 5. Он вставит это значение в предложенную строку на место фигурных скобок.

apple_string = "I have {}."
print(apple_string.format("5 apples"))
I have 5 apples.

Теперь метод format вставил на место заменителя строку «5 apples».

Множественная замена

В строке можно использовать несколько заменителей. Попробуйте добавить в строку ещё одну пару фигурных скобок, а в метод – ещё одно значение.

new_apple_string = "I love {} {}." #2 {} заменителя
print(new_apple_string.format("red", "apples")) #Значения нужно разделить запятой
I love red apples.

Метод str.format() может передавать несколько строк; для этого нужно разделить их запятыми, как показано в примере выше.

Попробуйте добавить в строку ещё несколько заменителей:

my_string = "I love {} {}, and have {} {}." #4 {} заменителя
print(my_string.format("red", " apples", 5, "apples")) #4 строки в методе
I love red apples, and have 5 apples.

Позиционные и именованные аргументы

Если фигурные скобки передаются без каких-либо параметров, Python вставит значения, переданные с помощью метода str.format (), по порядку, как это было в предыдущих примерах. Рассмотрим ещё один пример:

print("My friend {} has a pet {}!".format("Sam", " winged dinosaur"))
My friend Sam has a pet winged dinosaur!

Первая пара фигурных скобок заменяется первым значением метода, вторая пара – вторым значением. Значения метода выглядят так:

("Sam", " winged dinosaur")

Эти данные являются кортежем. Любое значение кортежа можно вызвать с помощью индекса – порядкового номера (начиная с 0).

Вы можете использовать эти индексы внутри фигурных скобок:

print("My friend {0} has a pet {1}!".format("Sam", " winged dinosaur"))

Это вернёт такой же результат:

My friend Sam has a pet winged dinosaur!

А теперь попробуйте поменять индексы местами:

print("My friend {1} has a pet {0}!".format("Sam", " winged dinosaur"))
My friend winged dinosaur has a pet Sam!

Если вы вызовете значение с индексом 2, а в методе значения с таким индексом нет, программа вернёт ошибку. Например:

print("My friend {2} has a pet {1}!".format("Sam", " winged dinosaur"))
IndexError: tuple index out of range

Это значит, что запрашиваемый индекс находится вне диапазона кортежа (в данном случае это числа между 0 и 1).

Добавьте ещё несколько заполнителей и значений, например:

print("Tom is a {}, {}, and {} {}!".format("happy", "smiling", "tall", "man"))
Tom is a happy, smiling, and tall man!

Без дополнительных параметров метод str.format() вставит значения по порядку.

Значения кортежа имеют следующие индексы:

Попробуйте изменить порядок внесения значений в строку с помощью индексов:

print("Tom is a {3}, {2}, and {1} {0}!".format("happy", "smiling", "tall", "man"))
Tom is a man, tall, and smiling happy!

Кроме позиционных аргументов существуют также именованные аргументы. Эти аргументы можно вызвать по имени. Например:

print("Tom {0} {1} a {pr}.".format("has", "made", pr = "pull request"))
Tom has made a pull request.

Именованный аргумент pr можно использовать вместе с позиционными. Позиционные и именованные аргументы позволяют изменять порядок внесения значений в строку:

print("Tom {pr} {1} a {0}.".format("has", "made", pr = "pull request"))
Tom pull request made a has.

Типы

В фигурные скобки можно добавить больше параметров. Попробуйте использовать синтаксис {field_name:conversion}, где field_name задаёт индекс аргумента метода str.format(), а conversion – тип данных с помощью односимвольного кода, который использует Python. Здесь мы используем такой код:

Попробуйте передать с помощью метода целое число как число с плавающей точкой, добавив тип f.

print("Sam ate {0:f} percent of a {1}!".format(75, "pizza"))
Sam ate 75.000000 percent of a pizza!

В первых фигурных скобках был использован синтаксис {field_name:conversion}, в остальных заполнителях используется только номер индекса.

Вы можете ограничить количество нулей после точки. Указывая тип f, вы можете дополнительно задать точность значения; для этого добавьте точку, затем укажите количество цифр, которое должно идти после запятой, а затем – сам тип.

Рассмотрим такой пример:

print("Sam ate {0:.3f} percent of a pizza!".format(75.765367))
Sam ate 75.765 percent of a pizza!

Как видите, несмотря на то, что в значении после точки идёт 6 символов, в строке отображается только три символа.

Попробуйте уменьшить количество символов после точки до одного.

print("Sam ate {0:.1f} percent of a pizza!".format(75.765367))
Sam ate 75.8 percent of a pizza!

Метод format округлит число до 75.8.

Попробуйте изменить тип данных на десятичные числа:

print("Sam ate {0:.d} percent of a pizza!".format(75.765367))
ValueError: Unknown format code "d" for object of type "float"

Чтобы вывести только целое число и опустить все символы после точки, используйте:

print("Sam ate {0:.0f} percent of a pizza!".format(75.765367))

При этом число с плавающей точкой не станет целым числом.

Отступы в переменных

Чтобы создать внутренние отступы в заполнителях, вы можете просто увеличить размер поля с помощью дополнительных параметров. Эта функция позволяет визуально организовать большое количество данных.

Для этого добавьте в фигурные скобки после индекса через двоеточие длину поля (в символах). Например:

print("Tom has {0:4} red {1:10}!".format(5, "apples"))
Sammy has 5 red apples !

По умолчанию строки выравниваются внутри поля по левому краю, а числа – по правому краю. Это можно изменить с помощью символов:

  • < — выравнивание по левому краю;
  • ^ — выравнивание по центру;
  • > — выравнивание по правому краю.

Символ указывается после двоеточия. Например, чтобы выровнять объект в первых фигурных скобках по левому краю, а во вторых – по центру, нужно ввести:

print("Tom has {0:<4} red {1:^10}!".format(5, "apples"))
Sammy has 5 red apples !

По умолчанию Python заполняет свободное пространство внутри поля пробелами. Вы можете выбрать другой символ для заполнения. Его нужно указать сразу после двоеточия. Например:

print("{:*^20s}".format("Hallo"))
******* Hallo********

Эти параметры можно комбинировать с другими параметрами, например:

print("Sam ate {0:5.0f} percent of a pizza!".format(75.765367))
Sam ate 76 percent of a pizza!

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

Переменные

Теперь вы умеете передавать методу str.format() целые числа, числа с плавающей точкой и строки.

Кроме того, метод str.format() может работать с переменными.

Рассмотрим такой пример:

nApples = 8
print("Tommy has {} apples today!".format(nApples))
Tommy has 8 apples today!

Переменную можно использовать и вместо исходной строки, например:

tommy = "Tommy has {} apples today!"
nApples = 8
print(tommy.format(nApples))
Tommy has 8 apples today!

Переменными можно заменить любую часть синтаксиса. Это упрощает работу с пользовательскими входными данными.

Организация данных

Функции форматирования позволяют структурировать большое количество данных. Чтобы сделать вывод удобочитаемым, можно увеличить размер поля и изменить выравнивание.

Рассмотрим типичный пример Python, который выведет число «i», «i*i» и «i*i*i» в диапазоне от 3 до 12:

for i in range(3,13):
print(i, i*i, i*i*i)
3 9 27
4 16 64
5 25 125
6 36 216
7 49 343
8 64 512
9 81 729
10 100 1000
11 121 1331
12 144 1728

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

Попробуйте отформатировать его:

for i in range(3,13):
print("{:3d} {:4d} {:5d}".format(i, i*i, i*i*i))

В данном случае фигурные скобки не содержат индекса. После двоеточия сразу идёт размер поля, затем тип данных (d). Таким образом, в каждом столбце окажется минимум один свободный символ.

3 9 27
4 16 64
5 25 125
6 36 216
7 49 343
8 64 512
9 81 729
10 100 1000
11 121 1331
12 144 1728

Также можно задать одинаковое количество символов в каждом столбце.

for i in range(3,13):
print("{:6d} {:6d} {:6d}".format(i, i*i, i*i*i))
3 9 27
4 16 64
5 25 125
6 36 216
7 49 343
8 64 512
9 81 729
10 100 1000
11 121 1331
12 144 1728

Также вы можете изменять выравнивание с помощью символов <, ^ и >, изменять тип данных, добавлять индексы.

Заключение

Форматирование в Python – это удобный и эффективный способ объединения строк и визуальной организации данных. Методы форматирования довольно просты, но их синтаксис не всегда очевиден. Тем не менее, с их помощью вы можете передавать переменные в строку и сделать вывод удобочитаемым.

Tags:

Недавно узнал, что блог время от времени находят по запросу "что означает %s в python". Вспоминаю себя – когда я начинал изучать Python, мне хотелось быстрых и понятных ответов (мол, "не морочь голову, пальцем покажи"). Для таких нетерпеливых эта статья.

Оглавление

Для начала несколько примеров

Форматирование строк:
>>> name = "Vasya" >>> print "My name is %s" % (name) My name is Vasya С указанием размера полей (перед "Vasya" стоит пять пробелов, т.е. всего десять символов): >>> print "My name is %10s. That"s my name." % (name) My name is Vasya. That"s my name. То же самое, но выровненное по левому краю: >>> print "My name is %-10s. That"s my name." % (name) My name is Vasya . That"s my name. Когда это может быть полезно: >>> drinks = {"Long Island": 3, "Bloody Mary": 2, "Margarita":4} >>> print "%-15s%-5s" % ("Name", "Qty") Name Qty >>> for k,v in drinks.items(): ... print "%-15s%-3s" % (k, v) ... Bloody Mary 2 Long Island 3 Margarita 4 Если понадобится вывести целую часть числа:
>>> num = 12.34 >>> print "%d" % (num) 12 Вперемешку:
>>> age = 25 >>> print "My name is %s. I"m %d." % (name, age) My name is Vasya. I"m 25.

Теперь вкратце как работает оператор %

Выражение форматирования можно условно разделить на три части:

Определение_формата + % + объект(ы)

Обозначения %s, %d, %g и т. п. - это форматы типов данных. Если вы знакомы с языком Си, то это тот же синтаксис, что используется для вывода на печать printf() .

Спецификации различных типов данных Python приведены в следующей таблице:

Формат Значение
"d" Целое десятичное число.
"i" Целое десятичное число.
"o" Восьмеричное число.
"u" Устаревший тип – то же что "d" .
"x" Шестнадцатеричное число (нижний регистр).
"X" Шестнадцатеричное число (верхний регистр).
"e" Вещественное число в экспоненциальном виде (нижний регистр).
"E" Вещественное число в экспоненциальном виде (верхний регистр).
"f"
"F" Вещественное число в десятичном виде.
"g" Вещественное число. Использует формат "f" или "e" в нижнем регистре.
"G" Вещественное число. Использует формат "F" или "E" в верхнем регистре.
"c" Один символ (или цифра).
"r" repr() .
"s" Строка, в которую любой объект Python конвертируется с помощью str() .
"%" Аргумент не конвертируется, выводится просто символ "%" .

Встроенная функция format()

Работает так: str.format()

В строке "поля для замены" заключаются в фигурные скобки {} . Все, что не заключено в скобки, воспринимается как обычный текст, которые копируется в неизменном виде. Чтобы передать в тексте символы фигурных скобок, их дублируют: {{ и }} .
Поля для замены форматируются следующим образом:

Поле_для_замены::= "{" [имя_поля] ["!" конверсия] [":" спецификация] "}" имя_поля::= имя_аргумента ("." имя_атрибута | "[" номер_элемента "]")* имя_аргумента::= [идентификатор | integer] имя_атрибута::= идентификатор индекс_элемента::= integer | строковый индекс строковый_индекс::= <любой символ кроме "]"> + конверсия::= "r" | "s" # str или repr спецификация::= <описано ниже> где
спецификация::= [[заглушка]выравнивание][знак][#][ширина][,][.точность][тип] заглушка::= <любой символ> выравнивание::= "<" | ">" | "=" | "^" знак::= "+" | "-" | " " ширина::= integer # ширина поля точность::= integer # знаки после десятичной запятой тип::= "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "s" | "x" | "X" | "%" Записывается так: >>> print """\n{0} ... Сидел на стене... {0} ... Свалился во сне.""".format("Шалтай-Болтай") Шалтай-Болтай Сидел на стене Шалтай-Болтай Свалился во сне.

Как видите, этот способ гораздо гибче оператора "%", так как одни и те же значения мы можем использовать повторно и в любом порядке. Также можно передать именованные аргументы, и тогда обращаться к ним будем не по номерам, а по именам.

Еще пример форматирования:

>>> toc = (... ("Первая глава", "3"), ... ("Вторая глава", "150") ...) >>> for line in toc: ... print("{:.

Загрузка...