Questo codice non è corretto a meno che tu non sappia qualcosa che noi non sappiamo:
if isinstance(data, bytes):
data = data.decode()
Non conosci (sembra) la codifica di data. Stai assumendo che sia UTF-8 , ma potrebbe essere sbagliato. Dato che non conosci la codifica, non hai testo . Hai byte, che potrebbero avere qualsiasi significato sotto il sole.
La buona notizia è che la maggior parte delle sequenze casuali di byte non sono UTF-8 valide, quindi quando si interrompe, si interromperà rumorosamente ( errors='strict'è l'impostazione predefinita) invece di fare silenziosamente la cosa sbagliata. La notizia ancora migliore è che la maggior parte di quelle sequenze casuali che sono UTF-8 valide sono anche ASCII valide, che ( quasi ) tutti sono d'accordo su come analizzare comunque.
La cattiva notizia è che non esiste un modo ragionevole per risolvere questo problema. Esiste un modo standard per fornire informazioni sulla codifica: utilizzare strinvece di bytes. Se un codice di terze parti ti ha consegnato un oggetto byteso bytearraysenza ulteriori informazioni o contesto, l'unica azione corretta è fallire.
Ora, supponendo che tu conosca la codifica, puoi usare functools.singledispatchqui:
@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, ...)
Questo non funziona con i metodi e datadeve essere il primo argomento. Se queste restrizioni non funzionano per te, usa invece una delle altre risposte.