Этот код неверен, если вы не знаете чего-то, чего мы не знаем:
if isinstance(data, bytes):
data = data.decode()
Вы (кажется) не знаете кодировку data. Вы предполагаете, что это UTF-8 , но это вполне может быть ошибкой. Поскольку вы не знаете кодировку, у вас нет текста . У вас есть байты, которые могут иметь любое значение под солнцем.
Хорошая новость заключается в том, что большинство случайных последовательностей байтов недействительны для UTF-8, поэтому, когда он прерывается, он будет громко ломаться ( errors='strict'по умолчанию) вместо того, чтобы молча делать неправильные вещи. Еще лучшая новость заключается в том, что большинство тех случайных последовательностей, которые оказываются действительными в кодировке UTF-8, также являются действительными ASCII, которые ( почти ) все согласны с тем, как их анализировать.
Плохая новость в том, что нет разумного способа исправить это. Существует стандартный способ предоставления информации о кодировке: использовать strвместо bytes. Если какой-то сторонний код передал вам объект bytesили bytearrayбез какого-либо дополнительного контекста или информации, единственное правильное действие - сбой.
Теперь, если вы знаете кодировку, вы можете использовать functools.singledispatchздесь:
@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, ...)
Это не работает с методами и dataдолжно быть первым аргументом. Если эти ограничения не работают для вас, используйте вместо этого один из других ответов.