Ten kod nie jest poprawny, chyba że wiesz coś, czego nie wiemy:
if isinstance(data, bytes):
data = data.decode()
Nie znasz (wydajesz się) znać kodowania data. Zakładasz, że to UTF-8 , ale to może być bardzo złe. Ponieważ nie znasz kodowania, nie masz tekstu . Masz bajty, które pod słońcem mogą mieć jakiekolwiek znaczenie.
Dobrą wiadomością jest to, że większość losowych sekwencji bajtów nie jest prawidłowym kodem UTF-8, więc kiedy to się zepsuje, będzie się łamać głośno ( errors='strict'jest to ustawienie domyślne) zamiast po cichu robić źle. Jeszcze lepszą wiadomością jest to, że większość tych losowych sekwencji, które okazały się być prawidłowymi kodami UTF-8, to również prawidłowe ASCII, które i tak ( prawie ) wszyscy zgadzają się co do sposobu parsowania.
Zła wiadomość jest taka, że nie ma rozsądnego sposobu, aby to naprawić. Istnieje standardowy sposób dostarczania informacji o kodowaniu: użyj strzamiast bytes. Jeśli jakiś kod innej firmy przekazał ci obiekt byteslub bytearraybez dalszego kontekstu lub informacji, jedyną poprawną czynnością jest niepowodzenie.
Zakładając, że znasz kodowanie, możesz użyć functools.singledispatchtutaj:
@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, ...)
To nie działa na metodach i datamusi być pierwszym argumentem. Jeśli te ograniczenia nie działają w Twoim przypadku, użyj jednej z pozostałych odpowiedzi.