Este código no es correcto a menos que sepa algo que nosotros no:
if isinstance(data, bytes):
data = data.decode()
No (parece) conocer la codificación de data. Está asumiendo que es UTF-8 , pero eso podría estar mal. Como no conoce la codificación, no tiene texto . Tienes bytes, que podrían tener cualquier significado bajo el sol.
La buena noticia es que la mayoría de las secuencias aleatorias de bytes no son UTF-8 válidas, por lo que cuando esto se rompe, se romperá en voz alta ( errors='strict'es lo predeterminado) en lugar de hacer lo incorrecto en silencio. La mejor noticia es que la mayoría de esas secuencias aleatorias que resultan ser UTF-8 válidas también son ASCII válidas, que ( casi ) todos están de acuerdo en cómo analizar de todos modos.
La mala noticia es que no existe una forma razonable de solucionar este problema. Existe una forma estándar de proporcionar información de codificación: use en strlugar de bytes. Si algún código de terceros le entregó un objeto bytesu bytearraysin más contexto o información, la única acción correcta es fallar.
Ahora, suponiendo que conozca la codificación, puede usar functools.singledispatchaquí:
@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, ...)
Esto no funciona con métodos y datadebe ser el primer argumento. Si esas restricciones no funcionan para usted, use una de las otras respuestas en su lugar.