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?

Chris AtLee
quelle
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.

Martijn Pieters
quelle
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)!

Jeremy Field
quelle