Python TypeError: Nicht leere Formatzeichenfolge, die an das Objekt .__ format__ übergeben wird


78

Ich habe kürzlich diese TypeError-Ausnahme getroffen, die ich nur sehr schwer debuggen konnte. Ich habe es schließlich auf diesen kleinen Testfall reduziert:

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

Das ist mir sowieso nicht klar. Die Problemumgehung für meinen Code bestand darin, die Byte-Zeichenfolge in Unicode zu dekodieren:

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

Was bedeutet diese Ausnahme? Gibt es eine Möglichkeit, dies klarer zu machen?


7
Wahrscheinlich erwähnenswert: Dies wurde erst TypeErrorin Python 3.4+ und betrifft alles, was erbt, objectohne es __format__auf dem Weg zu definieren (z None. B. class T(object): passusw.).
Henry Keiter

1
Hintergrundinformationen finden Sie unter bugs.python.org/issue7994
gerrit

2
Ich hatte auch dieses Problem und fand schließlich heraus, dass eine Variable, die einen Float enthalten sollte, tatsächlich enthalten war None. So '{0:.4f}'.format(bla)verursachte diese Ausnahme
SomethingSomething

Antworten:


77

bytesObjekte haben keine __format__eigene Methode, daher wird der Standardwert von objectverwendet:

>>> 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__

Es bedeutet nur, dass Sie nichts anderes als eine direkte, unformatierte, nicht ausgerichtete Formatierung für diese verwenden können. Konvertieren Sie explizit in ein Zeichenfolgenobjekt (wie beim Dekodieren bytesin str), um Unterstützung für Formatspezifikationen zu erhalten .

Sie können die Konvertierung mithilfe der !sZeichenfolgenkonvertierung explizit machen :

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

object.__format__ lehnt Formatzeichenfolgen explizit ab, um implizite Zeichenfolgenkonvertierungen zu vermeiden, insbesondere weil Formatierungsanweisungen typspezifisch sind.


11
macht Sinn, danke! Ich wünschte, der Fehler wäre intuitiver!
Chris AtLee

27

Dies passiert auch beim Formatieren None:

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

Das hat einen Moment gedauert (in meinem Fall, als Noneeine Instanzvariable zurückgegeben wurde)!

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.