最近PythonでJSONデータを取り扱った際にJSONモジュールの関数名を間違ったためにバグを踏んでしまったので、ここに記録しておきます。
関数名がまぎらわしい
文字列(str型)になっているJSON形式のリストデータをPythonのリストとして読み込みたかったのですが、ここでjson.load()を使ったところエラーが出てしまいました。
AttributeError: 'str' object has no attribute 'read'
あれ、使い方はあってるはずだよな、と思っていたのですが、そもそも使うべき関数を間違っていました。
この場合はjson.loadではなく、正しくはjson.loadsでした。
loadとloadsの違い
普段はVScodeで作業をしているのですが、関数名の補完機能がついているため「load」の関数が補完でヒットして、これをそのまま疑問を持たずに使いました。
loadも関数としてちゃんと存在していますが、ここで使うべきはloadsでした。
loadとloadsの違いを大雑把に以下に記載します。
- load : jsonファイルから読み込む(ファイルストリーム)
- loads : json形式の文字列(str型)から読み込む場合
json --- JSON エンコーダおよびデコーダ — Python 3.9.20 ドキュメント
loadsの「s」はおそらくStringのsから来ているかと思われるネーミングですね。末尾にちっちゃく「s」って書いてるだけで視認性がよくありません。
あと、実はloadsはstr型だけではなく、bytesとbytearrayも扱えるそうです。
dumpとdumpsの違い
これらもloadとloadsの違いに対応していて、dumpがファイルストリーム、dumpsが文字列への変換を担う関数です。
辞書型をJSONファイルに書き出したいときにはdumpを使って、辞書型を文字列にしたいときにはdumpsを使うといったところです。
関数名の末尾にちっちゃくsがついているか否かの違いですが、動作がまったく違うので気をつけたいところです。
コメント