私たちが知らないことを知らない限り、このコードは正しくありません。
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、最初の引数である必要があります。これらの制限が機能しない場合は、代わりに他の回答のいずれかを使用してください。