Kuzunoha-NEのブログ

プログラミングなどの勉強をしてます

【Python】byte型だけが入ったlistを全てstr型に変換したlistとして返す + アノテーションを少し

こんばんは、葛の葉です。

さて、私は最近、Redisを使っているのですが、Pythonを通して取得した場合、byte型で受け取ることになると思います。Listとして受け取った場合、List内全てがbyte型になってしまいます。今回はbyteが入ったリストを一括で変化するための関数を作りました。

環境

Python 3.6.5

コード

def byte_to_str(byte_list: list) -> list:
    return [i.decode('utf8') for i in byte_list]

少し変わった書き方が見えると思います。引数(byte_list: list) -> list: list-> listアノテーションと言って、注釈の意味になります。(byte_list: list)の個所のアノテーションは「引数に入れるのはリストで入れてください」と注釈しています。また、 -> listの個所は返り値の型がlistであることを注釈しています。ただ、あくまで注釈なので拘束力はありません。

もう一つ、返り値の[i.decode('utf8') for i in byte_list]の書き方はリスト内包表記となっております。

実行

test_list = [b'python',b'ruby', b'node', b'golang']
byte_to_str(test_list)
['python', 'ruby', 'node', 'golang']

さもありなん

アノテーションあれこれ

文字列を入れることもできるので説明しやすくていいですね。

def byte_to_str(byte_list: "byteだけが入ったlistを入れてね") -> "listで返します。":
    return [i.decode('utf8') for i in byte_list]

また、アノテーションには拘束力はないので、引数に文字列を入れることが出来てしまいます。以下は引数を文字列で渡しました。結果、strオブジェクトのAttributeErrorになっています。引数として読み込まれたtest変数が関数内で.decode('utf8')を呼び出そうとした際に起きたErrorです。str.decode('utf8')インスタンスが無いのでAttributeErrorとなります。

test = 'insert str'
byte_to_str(test)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in byte_to_str
  File "<stdin>", line 2, in <listcomp>
AttributeError: 'str' object has no attribute 'decode'

その他、アノテーションについて、詳しくはPEPの以下のリンクをチェック

www.python.org