zaki work log

作業ログやら生活ログやらなんやら

PythonでJSONデータ変換いろいろ

PythonJSONデータを扱ういろいろのメモ

オブジェクト -> JSON文字列 / json.dumps()

辞書や配列の変数をJSON文字列に変換

import json

curry = {
    'onion': 1,
    'coriander': '2tbsp',
    'cumin': '2tbsp',
    'turmeric': '2tsp',
    'white_pepper': '1tsp',
    'cooking_sake': '2tbsp',
    'salt': '1tsp',
    'sugger': '1tsp',
    'grape_seed_oil': '200g'
}

print(json.dumps(curry))

出力は以下の通り。

{"onion": 1, "coriander": "2tbsp", "cumin": "2tbsp", "turmeric": "2tsp", "white_pepper": "1tsp", "cooking_sake": "2tbsp", "salt": "1tsp", "sugger": "1tsp", "grape_seed_oil": "200g"}

人が読みやすいJSON文字列

前述のJSON変換時にindentオプションを追加すると、human readableになる。

print(json.dumps(curry, indent=2))

出力は以下の通り。

{
  "onion": 1,
  "coriander": "2tbsp",
  "cumin": "2tbsp",
  "turmeric": "2tsp",
  "white_pepper": "1tsp",
  "cooking_sake": "2tbsp",
  "salt": "1tsp",
  "sugger": "1tsp",
  "grape_seed_oil": "200g"
}

日本語(非ASCII)を含む場合のエスケープ抑止

デフォルトでは多バイト文字が入っているとUnicodeエスケープされて読みにくくなるが、オプションで制御可能。

import json

curry = {
    'onion': 1,
    'coriander': '大2',
    'cumin': '大2',
    'turmeric': '小2',
    'white_pepper': '小1',
    'cooking_sake': '大2',
    'salt': '小1',
    'sugger': '小1',
    'grape_seed_oil': '200グラム'
}

json_string = json.dumps(curry, indent=2)
print(json_string)

json_string = json.dumps(curry, indent=2, ensure_ascii=False)
print(json_string)

出力は以下の通り。

{
  "onion": 1,
  "coriander": "\u59272",
  "cumin": "\u59272",
  "turmeric": "\u5c0f2",
  "white_pepper": "\u5c0f1",
  "cooking_sake": "\u59272",
  "salt": "\u5c0f1",
  "sugger": "\u5c0f1",
  "grape_seed_oil": "200\u30b0\u30e9\u30e0"
}
{
  "onion": 1,
  "coriander": "大2",
  "cumin": "大2",
  "turmeric": "小2",
  "white_pepper": "小1",
  "cooking_sake": "大2",
  "salt": "小1",
  "sugger": "小1",
  "grape_seed_oil": "200グラム"
}

オブジェクト -> JSONファイル / json.dump()

json.dumps()JSON文字列化してファイルへ書き込みしてもよいが、json.dump()を使えば文字列を作らず直接書き込める。

import json

curry = {
    'onion': 1,
    'coriander': '2tbsp',
    'cumin': '2tbsp',
    'turmeric': '2tsp',
    'white_pepper': '1tsp',
    'cooking_sake': '2tbsp',
    'salt': '1tsp',
    'sugger': '1tsp',
    'grape_seed_oil': '200g'
}

with open('data.json', mode='w') as f:
    json.dump(curry, f, indent=2)

これでdata.jsonファイルの中身は以下の通り。

{
  "onion": 1,
  "coriander": "2tbsp",
  "cumin": "2tbsp",
  "turmeric": "2tsp",
  "white_pepper": "1tsp",
  "cooking_sake": "2tbsp",
  "salt": "1tsp",
  "sugger": "1tsp",
  "grape_seed_oil": "200g"
}

JSON文字列 -> オブジェクト / json.loads()

前述のcurryオブジェクトと、そこからJSON変換した文字列をベースに、そこからPythonのオブジェクトに再度変換。

import json

curry = {
    'onion': 1,
    'coriander': '2tbsp',
    'cumin': '2tbsp',
    'turmeric': '2tsp',
    'white_pepper': '1tsp',
    'cooking_sake': '2tbsp',
    'salt': '1tsp',
    'sugger': '1tsp',
    'grape_seed_oil': '200g'
}

json_string = json.dumps(curry, indent=2)
print(type(json_string))

obj = json.loads(json_string)
print(type(obj))
print(obj)

print(obj == curry)

出力は以下の通り。

<class 'str'>
<class 'dict'>
{'onion': 1, 'coriander': '2tbsp', 'cumin': '2tbsp', 'turmeric': '2tsp', 'white_pepper': '1tsp', 'cooking_sake': '2tbsp', 'salt': '1tsp', 'sugger': '1tsp', 'grape_seed_oil': '200g'}
True

json.dumps()で変換したJSON文字列は、json.laods()を使うとオブジェクトに変換できる。
型はdictになり、元のcurryオブジェクトと一致している。

ちなみに上記はindent=2を付与しているが、オプションがなくても結果は同一。

JSONファイル -> オブジェクト / json.load()

JSON形式のファイルをPythonオブジェクトとして読み込む。

import json
with open(json_file_path) as f:
    d = json.load(f)

これでdJSONデータがそのままPythonオブジェクト(辞書やリスト、文字列など)としてセットされる。

JSONのHTTPレスポンス -> オブジェクト

REST APIを叩いた時など。

urllib.request

import urllib.request
import json

req = urllib.request.Request('https://api.example.org/api/v2/')
with urllib.request.urlopen(req) as res:
    d = json.load(res)

requests

requestsjsonを使う必要がなく、JSONを内部でパースする機能を備えている。

import requests

r = requests.get('https://api.example.org/api/v2/')
d = r.json()