спецификатор формата f-строки с None выдает TypeError - PullRequest
0 голосов
/ 10 октября 2018

Использование простых f-строк с объектом NoneType работает:

>>> a = None
>>> f'{a}'
'None'

Однако при использовании спецификатора формата оно прерывается --- как и str.format ():

>>> f'{a:>6}'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported format string passed to NoneType.__format__

>>> '{:>6}'.format(a)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported format string passed to NoneType.__format__

Неожиданно (по крайней мере для меня) работает старое форматирование строк в стиле C:

>>> '%10s' % a
'      None'

Что здесь происходит?Я не понимаю, почему f'{a:>6}' не оценивается как ' None'.Почему спецификатор формата должен нарушать его?

Это ошибка в python?Если это ошибка, как бы я ее исправить?

Ответы [ 3 ]

0 голосов
/ 10 октября 2018

None не поддерживает спецификаторы формата.Каждый тип объекта должен определить, как он хочет обрабатывать спецификаторы формата, и по умолчанию отклоняет их :

Метод __format__ самого object сам вызываетОшибка типа, если передана любая непустая строка.

None наследует это значение по умолчанию.

Вы, похоже, ожидаете, что None будет обрабатывать спецификаторы формата так же, как строки,где '{:>6}'.format('None') == ' None'.Это звучит так, как будто вы ожидаете, что все типы будут обрабатывать спецификаторы формата так, как это делают строки, или вы ожидаете, что поведение строки будет по умолчанию.Способ, которым строки обрабатывают спецификаторы формата, специфичен для строк;другие типы имеют свою собственную обработку.


Вы можете подумать, эй, почему %10s тоже не терпит неудачу?Во-первых, s запрашивает преобразование аргумента в строку с помощью str перед любой дальнейшей обработкой.Во-вторых, вся обработка спецификаторов преобразования при форматировании строки в стиле printf выполняется с помощью str.__mod__;он никогда не делегирует аргументы, чтобы выяснить, что означает спецификатор преобразования.

0 голосов
/ 25 апреля 2019

Принятый ответ выше объясняет почему.Решение, которое я эффективно использовал, это что-то вроде:

f"{mystring:.2f}" if mystring is not None else ""
0 голосов
/ 10 октября 2018

None не является строкой, поэтому f'{None:>6}' не имеет смысла.Вы можете преобразовать его в строку с f'{None!s:>6}'.!a, !s и !r вызывают ascii(), str() и repr() соответственно для объекта.

...