web-dev-qa-db-ja.com

Python TypeError:オブジェクトに渡される空でないフォーマット文字列。__format__

最近、この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__

とにかく、これは非常に非自明です。私のコードの回避策は、バイト文字列をユニコードにデコードすることでした:

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

この例外の意味は何ですか?もっと明確にする方法はありますか?

73
Chris AtLee

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__

これは、これらに対してまっすぐにフォーマットされていない整列されていないフォーマット以外は使用できないことを意味します。明示的に文字列オブジェクトに変換して(bytesstrにデコードすることで行ったように) format spec support を取得します。

!s文字列変換を使用して、変換を明示的に行うことができます。

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

object.__format__は、明示的にフォーマット文字列を拒否して、暗黙的なストリング変換を回避します。これは、特にフォーマット命令がタイプ固有であるためです。

69
Martijn Pieters

これは、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がインスタンス変数によって返されていたとき)!

23
Jeremy Field