Использование! S vs.: s для форматирования строки в Python

Мне очень интересно :s строка формата :s в Python 3. В документации говорится !s – это преобразование и что :sformat_spec .

Он также говорит, что !s применит str() , но он не говорит ничего подобного :s . Я думаю, что между ними нет существенной разницы, но я хочу быть уверен. Кто-нибудь может это прояснить?

Пример кода:

 print("{!s}".format("this")) print("{:s}".format("that")) # I want to be sure that these two are processed identically internally 

Это все еще запутанно, но позвольте мне завернуть мои собственные (непрофессиональные) слова.

  1. type("whatever".format) всегда str .
  2. Используйте !s если вы хотите преобразовать объект в str перед форматированием.
  3. :s означает, что объект (или преобразованный объект) будет обрабатываться как str во время некоторого внутреннего процесса форматирования. Это format_spec по умолчанию.

Здесь что-то не так?

3 Solutions collect form web for “Использование! S vs.: s для форматирования строки в Python”

!s и его братья !a и !r применяют str() , ascii() и repr() соответственно перед интерполяцией и форматированием. Они называются флагами преобразования и являются частью спецификации синтаксиса форматирования строки , а не спецификацией форматирования каждого поля, применяемой к значениям при интерполяции:

Поле преобразования вызывает принуждение типа перед форматированием . Обычно задание форматирования значения выполняется методом __format__() самого значения. Однако в некоторых случаях желательно принудительно форматировать тип как строку, переопределяя собственное определение форматирования. Преобразуя значение в строку перед вызовом __format__() , обычная логика форматирования обходит.

Смелый акцент мой.

:s применяется только после преобразования результата преобразования (или исходного объекта, если не было применено преобразование), и только если метод __format__ для типа объекта поддерживает этот параметр форматирования. Обычно только объекты типа str поддерживают этот форматтер; он существует как по умолчанию, главным образом потому, что мини-язык спецификации формата допускает существование символа типа и потому, что формат форматирования более старого формата % printf имеет формат %s . Если вы попытались применить тип s к объекту, который его не поддерживает, вы получите исключение.

Используйте !s (или !a или !r ), когда у вас есть объект, который сам по себе не является строкой, и либо не поддерживает форматирование в противном случае (не все типы), либо будет отличаться от своих str() , ascii() или repr() :

 >>> class Foo: ... def __str__(self): ... return "Foo as a string" ... def __repr__(self): ... return "<Foo as repr, with åéæ some non-ASCII>" ... def __format__(self, spec): ... return "Foo formatted to {!r} spec".format(spec) ... >>> print("""\ ... Different conversions applied: ... !s: {0!s:>60s} ... !r: {0!r:>60s} ... !a: {0!a:>60s} ... No conversions: {0:>50s} ... """.format(Foo())) Different conversions applied: !s: Foo as a string !r: <Foo as repr, with åéæ some non-ASCII> !a: <Foo as repr, with \xe5\xe9\xe6 some non-ASCII> No conversions: Foo formatted to '>50s' spec 

Примечание: все форматирование, указанное спецификацией формата, несет ответственность за метод __format__ ; последняя строка не применяет операцию выравнивания в спецификации форматирования >50s , метод Foo.__format__ использует ее только как литерал в операции форматирования (здесь используется преобразование !r ).

С другой стороны, для преобразованных значений используется метод str.__format__ а вывод выравнивается вправо в поле шириной 50 символов, заполненном пробелами слева.

Вам не повезло, что вы использовали строки как значение для форматирования. Используя практически любой другой объект, вы получите, как это не то же самое.

В (насколько я могу) условия непрофессионала:

  • Отсутствие или наличие флага преобразования указывает тип значения, которое мы собираемся форматировать, и, по степени, кто __format__ мы будем звонить. Как указывает Марджин, используя это, мы можем обойти определенное поведение и рассматривать значение более универсально (например, строку). Он поставляется в трех разных вариантах, которые соответствуют трем различным способам, которые объект может выбрать для представления себя как строки.
  • Спецификатор типа в сочетании с другими спецификаторами указывает, каким образом должен быть представлен тип, который мы имеем . Для строк нет богатого набора опций (строка представлена ​​как есть), но для таких типов, как int s, вы можете иметь разные презентации.

Я действительно думаю, что этот type , вероятно, является запутанным именем, чтобы дать этот спецификатор.

Из документации, Форматирование строки Python :

Поле field_name необязательно следует за полем преобразования, которому предшествует восклицательный знак «!» И format_spec, которому предшествует двоеточие «:».

Так что нет, это не то же самое.

Например:

Если вы хотите напечатать float как строку, вам потребуется преобразование (float → string).

 "{!s}".format(2.1457) >>> 2.1457 type("{!s}".format(2.1457)) >>> <type 'str'> 

Если вы не используете знак перехода, вы получите сообщение об ошибке.

 "{:s}".format(2.1457) >>> ValueError: Unknown format code 's' for object of type 'float' 
  • Преобразование знака минус-символа Юникода (из титлебелей matplotlib)
  • Как изменить строковое представление класса Python?
  • печатающая переменная, содержащая строку и две другие переменные
  • Почему такие языки, как Java, различают строку и char, а другие нет?
  • Есть ли способ сравнить арабских персонажей без учета их начальной / медиальной / окончательной формы?
  • Определение того, сколько раз подстрока встречается в строке в Python
  • AttributeError: объект 'str' не имеет атрибутов 'items'
  • Извлечение URL-ссылки с использованием регулярного выражения re-string matching - Python
  •  
    Interesting Posts for Van-Lav
    Python - лучший язык программирования в мире.