Python TypeError: непустий рядок формату передано об'єкту .__ format__


78

Нещодавно я вдарився до цього винятку TypeError, який мені було дуже важко налагодити. Врешті-решт я звів його до цього невеликого тесту:

>>> "{:20}".format(b"hi")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: non-empty format string passed to object.__format__

Для мене це все одно дуже неочевидно. Обхідним шляхом для мого коду було декодування рядка байтів в unicode:

 >>> "{:20}".format(b"hi".decode("ascii"))
 'hi                  '

Що означає цей виняток? Чи є спосіб зробити це більш чітким?


7
Можливо, варто зазначити: це стало лише TypeErrorPython 3.4+, і воно впливає на все, що успадковується, objectбез визначення __format__в дорозі (наприклад None; class T(object): passтощо).
Henry Keiter

1
Для довідкової інформації див. Bugs.python.org/issue7994
gerrit

2
У мене теж була ця проблема, нарешті з'ясувалося, що змінна, яка повинна містити float, насправді міститься None. Таким чином '{0:.4f}'.format(bla)спричинився цей виняток
SomethingSomething

Відповіді:


77

bytesОб'єкти не мають __format__власного методу, тому використовується значення за замовчуванням з object:

>>> bytes.__format__ is object.__format__
True
>>> '{:20}'.format(object())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: non-empty format string passed to object.__format__

Це просто означає, що ви не можете використовувати на них що-небудь, крім прямого, неформатованого незрівнянного форматування. Явне перетворення в строковому об'єкт (як ви це робили під час декодування bytesв str) , щоб отримати формат SPEC підтримки .

Ви можете зробити перетворення явним, використовуючи !sперетворення рядків:

>>> '{!s:20s}'.format(b"Hi")
"b'Hi'               "
>>> '{!s:20s}'.format(object())
'<object object at 0x1100b9080>'

object.__format__ явно відхиляє рядки форматування, щоб уникнути неявних перетворень рядків, зокрема, оскільки інструкції з форматування специфічні для типу.


11
має сенс, дякую! Я хотів би, щоб помилка була більш інтуїтивно зрозумілою!
Chris AtLee

27

Це також трапляється при спробі форматування None:

>>> '{:.0f}'.format(None)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: non-empty format string passed to object.__format__

Це зайняло хвилину, щоб вирішити (у моєму випадку, коли Noneповерталася змінною екземпляра)!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.