paloma blog

NWエンジニアやってます。主に自宅環境のお遊びを書きます。Pythonもちょっと。タイトルは好きなカクテルから。

json型と辞書型って何が違うの?

ちょっと前の話

APIjsonをPOSTするときありますよね。
私はknowledgeの記事か何かをPythonを使ってAPIから更新しようとしました。

こんな中身(例)

article = {
    'title': 'タイトルだよ',
    'text': '中身だよ'
    }

が、詳細は忘れてしまいましたがエラーでPOSTできませんでした。
stackoverflowかなにかで調べたらjson.dumpしろとあったので試したところ上手くいきました。

何が違うの?

私はpythonをよく使いますがpythonの辞書型とjsonって書き方同じですよね。
何をエラーになることがあるんでしょうか。

という訳でちょっと調べました。

検証環境

WSLのubuntu18です。

masashi@DESKTOP-N095TND:~$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 18.04.2 LTS
Release:        18.04
Codename:       bionic
masashi@DESKTOP-N095TND:~$ uname -a
Linux DESKTOP-N095TND 4.4.0-17763-Microsoft #864-Microsoft Thu Nov 07 15:22:00 PST 2019 x86_64 x86_64 x86_64 GNU/Linux
masashi@DESKTOP-N095TND:~$ python3 --version
Python 3.6.9

結果は一発で出た

type関数で一発でした。

  • 変数
>>> type(article)
<class 'dict'>
>>> type(json.dumps(article))
<class 'str'>
  • 辞書型: そのまま辞書型
  • json型: 文字列

だったんですね。
辞書型データをPOSTしようとしてこけたってことですね。

dump, loadで変換する

厳密にはdumpsとloadsです。
dump, loadはファイルを読み込むとき使う?って感じです。

jsonの関数で辞書型と文字列の行き来が出来るみたいです。
特定の値を取りたいときは辞書型にしないと取れませんね。
(findで頑張れば無理くりで取れそうですが)

  • dumps: 辞書型 → 文字列

ヘルプ

    dumps(obj, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw)
        Serialize ``obj`` to a JSON formatted ``str``.
  • loads: 文字列 → 辞書型

ヘルプ

    loads(s, *, encoding=None, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)
        Deserialize ``s`` (a ``str``, ``bytes`` or ``bytearray`` instance
        containing a JSON document) to a Python object.

dumpsだとエラーになりますが、
json型をloadsすれば辞書型になり値が取れます。

>>> json.dumps(article)['title'] # 辞書 → json
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: string indices must be integers
>>>
>>> json.loads(json.dumps(article))['title'] # json → 辞書
'タイトルだよ'
>>>

なるほどねー

むすび

何となく使っていたjsonですが、整理したことで実態がわかりました。
(検証としては薄っぺらーいですが)

最近APIは可読性の観点でxmlよりjsonが主流になっていると思うので
これからバンバン使っていきたいです。

参考サイト

json --- JSON エンコーダおよびデコーダ — Python 3.8.1 ドキュメント