1. ホーム
  2. python

[解決済み] Pythonでオブジェクトがbytesライクであるかどうかを判断する適切な方法は何ですか?

2022-09-27 08:56:57

質問

私は、以下のようなコードを持っています。 str を期待するコードがありますが、これは bytes を次のように処理します。

if isinstance(data, bytes):
    data = data.decode()

残念ながら,これは bytearray . あるオブジェクトが以下のいずれかであるかどうかを調べる、より一般的な方法はありますか? bytes または bytearray なのか、それとも両方チェックすればいいのでしょうか? それとも hasattr('decode') は、私が感じるほど悪いのでしょうか?

どのように解決するのですか?

ここで使えるアプローチはいくつかあります。

アヒルのタイピング

Pythonは アヒルの型付け であるため、単純に以下のようにすることもできます(通常提案される方法と思われます)。

try:
    data = data.decode()
except (UnicodeDecodeError, AttributeError):
    pass

を使うことができます。 hasattr を使用することもできますし、おそらくうまくいくでしょう。もちろん、これは .decode() メソッドが文字列を返し、厄介な副作用がないことが前提です。

個人的には、例外か hasattr メソッドのどちらかをお勧めしますが、どちらを使うかはあなた次第です。

str()を使う

この方法は一般的ではありませんが、可能です。

data = str(data, "utf-8")

他のエンコーディングも許容されます。ちょうどバッファプロトコルの .decode() . また、第3パラメータを渡してエラー処理を指定することもできます。

シングルディスパッチ汎用関数 (Python 3.4+)

Python 3.4 以降では、シングルディスパッチジェネリック関数と呼ばれる気の利いた機能があります。 functools.singledispatch . これは少し冗長ですが、より明示的でもあります。

def func(data):
    # This is the generic implementation
    data = data.decode()
    ...

@func.register(str)
def _(data):
    # data will already be a string
    ...

のための特別なハンドラを作ることもできます。 bytearraybytes オブジェクトを作成することができます。

注意 : シングルディスパッチ関数は最初の引数に対してのみ動作します! これは意図的な機能で PEP 433 を参照してください。 .