web-dev-qa-db-fra.com

Python TypeError: chaîne de format non vide transmise à l'objet .__ format__

J'ai récemment frappé cette exception TypeError, que j'ai trouvé très difficile à déboguer. Je l'ai finalement réduit à ce petit cas de test:

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

C'est très peu évident, pour moi de toute façon. La solution de contournement pour mon code consistait à décoder la chaîne d'octets en unicode:

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

Quel est le sens de cette exception? Y a-t-il un moyen de le rendre plus clair?

73
Chris AtLee

Les objets bytes n'ont pas de __format__ Méthode propre, le paramètre par défaut de object est utilisé:

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

Cela signifie simplement que vous ne pouvez pas utiliser autre chose que du formatage non aligné aligné sur le dessus, non formaté. Convertissez explicitement en objet chaîne (comme vous l'avez fait en décodant bytes en str) pour obtenir prise en charge des spécifications de format .

Vous pouvez rendre la conversion explicite en utilisant le !s conversion de chaîne:

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

object.__format__ rejette explicitement les chaînes de format pour éviter les conversions implicites de chaînes, notamment parce que les instructions de formatage sont spécifiques au type.

69
Martijn Pieters

Cela se produit également lorsque vous essayez de formater None:

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

Cela a pris un moment pour résoudre le problème (dans mon cas, lorsque None était renvoyé par une variable d'instance)!

23
Jeremy Field