Ce code n'est pas correct sauf si vous savez quelque chose que nous ignorons:
if isinstance(data, bytes):
data = data.decode()
Vous ne connaissez pas (semblez-vous) le codage de data. Vous supposez que c'est UTF-8 , mais cela pourrait très bien être faux. Puisque vous ne connaissez pas l'encodage, vous n'avez pas de texte . Vous avez des octets, qui pourraient avoir n'importe quelle signification sous le soleil.
La bonne nouvelle est que la plupart des séquences aléatoires d'octets ne sont pas UTF-8 valides, donc quand cela se brise, il se cassera bruyamment ( errors='strict'c'est la valeur par défaut) au lieu de faire la mauvaise chose en silence. La meilleure nouvelle est que la plupart de ces séquences aléatoires qui se trouvent être du UTF-8 valide sont également de l'ASCII valide, que ( presque ) tout le monde s'accorde de toute façon sur la façon d'analyser.
La mauvaise nouvelle est qu'il n'existe aucun moyen raisonnable de résoudre ce problème. Il existe une manière standard de fournir des informations d'encodage: utilisez strplutôt que bytes. Si un code tiers vous a remis un objet bytesou bytearraysans autre contexte ou information, la seule action correcte est d'échouer.
Maintenant, en supposant que vous connaissez l'encodage, vous pouvez utiliser functools.singledispatchici:
@functools.singledispatch
def foo(data, other_arguments, ...):
raise TypeError('Unknown type: '+repr(type(data)))
@foo.register(str)
def _(data, other_arguments, ...):
@foo.register(bytes)
@foo.register(bytearray)
def _(data, other_arguments, ...):
data = data.decode('encoding')
return foo(data, other_arguments, ...)
Cela ne fonctionne pas sur les méthodes et datadoit être le premier argument. Si ces restrictions ne fonctionnent pas pour vous, utilisez plutôt l'une des autres réponses.