【Python】 Python ~ 基本編 / JSON ~

■ はじめに

Python での JSON の読み込み・書き込みを行う

目次

【0】使用上の注意
【1】JSON <=> 文字列
【2】JSONの読み書き
【3】JSONインスタンスをコピーする
【4】JSONをマージする

【0】使用上の注意

1)文字列⇒JSONへの変換において、値をダブルクォーテーションマーク囲む必要がある
2)末尾にカンマを入れるのはNG

1)文字列⇒JSONへの変換において、値をダブルクォーテーションマーク囲む必要がある

import json

# OK : 値をダブルクォーテーションマーク囲んでいる
json_text = '{ "aaa1":"hello", "aaa2":"world" }'
json_values = json.loads(json_text)
for v, k in json_values.items():
  print("{} : {}".format(v, k))

# ★NG : 値をダブルクォーテーションマーク囲んでいない
json_text = "{ 'aaa1':'hello', 'aaa2':'world' }"
json_values = json.loads(json_text)
# json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 3 (char 2)

2)末尾にカンマを入れるのはNG

import json

with open('hello.json', 'r') as file:
  json_dict = json.load(file) # ★ここで例外★
  print(json_dict)

hello.json

{
  "Name": "Mike",
  "Age": 24, <= ★ここにカンマがある、ダメ、絶対★
}

例外内容

raceback (most recent call last):
  File "c:/xxxx/demo.py", line 4, in <module>
    json_dict = json.load(file)
 ... 略 ...
json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 4 column 1 (char 33)

【1】JSON <=> 文字列

1)JSON => 文字列

# json.dumps() を使用する

import json
json_text = json.dumps(json_dist)

文字列 => JSON

# json.loads() を使用する

import json
json_values = json.loads(json_text)

2)JSON <=> 文字列

import json

if __name__ == '__main__':
  json_dist = {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}
  print(type(json_dist))
  print(json_dist)
  print('************')

  # JSON to string
  json_text = json.dumps(json_dist)
  print(type(json_text))
  print(json_text)
  print('************')

  # string to JSON
  json_values = json.loads(json_text)
  print(type(json_values))
  print(json_values)

出力結果

<class 'dict'>
{'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}
************
<class 'str'>
{"key1": "value1", "key2": "value2", "key3": "value3"}
************
<class 'dict'>
{'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}

【2】JSONの読み書き

1)JSONの読み込み

json_file = open('members.json', 'r')
json_dict = json.load(json_file)

2)JSONの書き込み

json_file = open('output.json', 'w')
json.dump(input_dict, json_file)

サンプル:読み込み

demo.py

import json

def main():
    json_file = open('members.json', 'r')
    json_dict = json.load(json_file)
    for key, values in json_dict.items():
        print(key)
        print(values['name'])
        print(values['birth_day'])
        print('*******************')

if __name__ == '__main__':
    main()

members.json

{
    "Member01":{
        "name":"Mike",
        "birth_day": "2019-10-12"
    },
    "Member02":{
        "name":"Tom",
        "birth_day": "2002-12-31"
    }
}

出力結果

Member01
Mike
2019-10-12
*******************
Member02
Tom
2002-12-31
*******************

サンプル:書き込み

import json

def main():
    input_dict = {"name": "Smith", "birth_day": "2002-12-21", "gender": "man"}
    json_file = open('output.json', 'w')
    json.dump(input_dict, json_file)

if __name__ == '__main__':
    main()

出力結果 : output.json

{"name": "Smith", "birth_day": "2002-12-21", "gender": "man"}

【3】JSONインスタンスをコピーする

<json>.copy() を使う

サンプル

import json

input_dict = {"name": "Smith", "birth_day": "2002-12-21", "gender": "man"}
clone_dict = input_dict.copy()
clone_dict["name"] = "Mike"

# {'name': 'Smith', 'birth_day': '2002-12-21', 'gender': 'man'}
print(input_dict)
# {'name': 'Mike', 'birth_day': '2002-12-21', 'gender': 'man'}
print(clone_dict)

【4】JSONをマージする

<json1>.update(<json2>) を使う

※ キーが重複する場合

⇒ 引数 <json2> で上書きされる

サンプル

import json

input1_dict = {"name": "Smith", "birth_day": "1967-08-11", "gender": "man"}
input2_dict = {"birth_day": "2012-12-23", "occupation": "IT", "note": "Hello world"}
input1_dict.update(input2_dict)

# {'name': 'Smith', 'birth_day': '2012-12-23', 'gender': 'man', 'occupation': 'IT', 'note': 'Hello world'}
print(input1_dict)

参考文献

https://qiita.com/Morio/items/7538a939cc441367070d

関連記事

Python ~ 基本編 / 文字列 ~
https://dk521123.hatenablog.com/entry/2019/10/12/075251
Python ~ 基本編 / astモジュール ~
https://dk521123.hatenablog.com/entry/2021/10/01/000000
Python ~ 基本編 / YAML
https://dk521123.hatenablog.com/entry/2019/10/16/225401