python jsonモジュールの覚え書き　データの取得、ファイルへの読み書き

#Pythonでのjsonデータの処理について
Pythonのjsonモジュールでjsonファイルからの読み込み、データの文字列 ⇔ 辞書型変換、ファイルへの保存を行う。
[【Python入門】JSON形式データの扱い方](https://qiita.com/Morio/items/7538a939cc441367070d)を参考に、複数箇所引用した上で、自分用に注釈、変更している。
#jsonとは
>JSON は「JavaScript Object Notation」の略で、「JavaScript 言語の表記法をベースにしたデータ形式」と言えます。
>JSON では、ある数値と、その数値の名前であるキーのペアをコロンで対にして、それらをコンマで区切り、全体を波かっこで括って表現します。

【参考１】
(つまりPythonの辞書型に似ている)。


#jsonファイルの読み込みと型変換
##dict型としての読み込み
↓このようなjsonファイルがある【参考１】。

```json:test.json
{
 "book1":{
"title": "Python Beginners",
 "year": 2005 ,
"page": 399
},
"book2":{
 "title": "Python Developers",
 "year": 2006 ,
"page": 650
 }
}
```
まずはload関数を実行する。実行場所と同じディレクトリにtest.jsonがあるとする。


```python:jikkou1
import json
var1 = open('test.json','r')    #第一引数はtest.jsonまでのパス。jsonファイルを開く
var2 = json.load(var1)    #開いたファイルを JSON として読み込む
var1.close()    #ファイルが開いたままなので閉じる。
```
var1,var2は任意の変数。jsonファイルを絶対パスで指定するならば、
var0=open('C:/Users/user_name/json_directory/test.json','r')
のように / でディレクトリを区切る。

下は実行結果の確認

```python:kakunin1
#それぞれの変数の型を調べてみる。
In [81]: type(var1)
Out[81]: _io.TextIOWrapper    #これはファイルのオブジェクト

In [82]: type(var2)
Out[82]: dict                 #var2は辞書型

In [85]: import pprint        #整形出力のモジュール
In [86]: pprint.pprint(var2)    #var2の内容を整形して出力
Out[86]: {'book1': {'page': 399, 'title': 'Python Beginners', 'year': 2005},
          'book2': {'page': 650, 'title': 'Python Developers', 'year': 2006}}
```
In [85]: やOut[86]: はIPythonでの表示、実際には入力、出力しない。
結果から、jsonファイルを読み込んで辞書型の変数として扱うことができている。
###Pythonでのjsonデータの型は２種類
文字列型(str型)と辞書型(dict型)である。
文字列型では、階層の情報までを文字列に含んで、１行の文字列としてデータを格納している。辞書型では、元々持っている階層構造を活かしてjsonの情報を扱っている。

##jsonデータの型変換　dict → str
JSON ファイルを load 関数で読み込むと、Python で扱いやすいように辞書型で保存される。文字列型として扱いたい場合は、辞書型から文字列型へ変換する。辞書型から JSON 形式の文字列への変換は dumps 関数を使う。

```python:jikkou2
import json

var1 = open('test.json', 'r')    #ファイルを開く
var2 = json.load(var1)           #辞書型で読み出し
var3 = json.dumps(var2)          #文字列型に変換
var1.close()                     #開いたファイルは閉じる。
```
jikkou1からdumps文が追加されている。

```Python:kakunin2
In [91]: type(var1)
Out[91]: _io.TextIOWrapper

In [92]: type(var2)
Out[92]: dict

In [93]: type(var3)
Out[93]: str
#つまりvar2(dict型)がvar3(str型)に変換されている
In [94]: print(var3)
Out[94]: {"book1": {"title": "Python Beginners", "year": 2005, "page": 399}, "book2": {"title": "Python Developers", "year": 2006, "page": 650}}

```
>dumps は辞書型を引数にとり、それを文字列に変換して返す関数です。

##jsonデータの変換　str → dict
逆に文字列型から辞書型への変換も行える。
loads関数を用いる。

```python:jikkou3
import json

var1 = open('test.json', 'r')
var2 = json.load(var1)
var3 = json.dumps(var2)
var4 = json.loads(var3)
var1.close()
```
確認してみる。

```python:kakunin3
In [85]: import pprint    #整形出力のモジュール
In [97]: type(var4)
Out[97]: dict

In [98]: pprint.pprint(var4)
Out[98]: {'book1': {'page': 399, 'title': 'Python Beginners', 'year': 2005},
          'book2': {'page': 650, 'title': 'Python Developers', 'year': 2006}}
```
結果からvar4は辞書型になっている。

#jsonデータのファイルへの書き込み＆保存

##辞書型を使って書き込み
読み込んだり、作成したりしたjsonデータをファイルへ書き込み、保存していく。
同じディレクトリにsave.json　、save.txtを作成して保存する。

```python:jikkou4
import json
var1 = open('test.json', 'r')    #第一引数はtest.jsonまでのパス。読み込みたいjsonファイルを開く
var2 = json.load(var1)           #辞書型として読み込み

var5 = open('save.json', 'w')    #第一引数は保存したいファイルのパス。
#var5 = open('save.txt', 'w')    #txtファイルでも同様に操作できる
json.dump(var2, var5)
var5.close()    #close()を実行した時点で保存される。
```
'w'モード(上書き)でopen()を実行したとき、指定したファイルが存在しなければファイルが新たに作成され、存在すれば上書きされる。続けて書きたい場合は'a'モードでファイルを開く(多分使わない)。
###結果
![2019-09-15 (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317707/7d432527-dc12-f628-1abb-7cc757452a1c.png)

ファイルが作成されている。
##文字列型を使って書き込み
文字列型からjsonファイルを作成するときは、単純にopen()関数の機能を使えば良い。

```python:jikkou5
var1 = open('test.json', 'r')    #読み込みたいjsonファイルを開く
var2 = json.load(var1)           #辞書型として読み込み
var3 = json.dumps(var2)          #文字列型へ変換

var5 = open('save.json', 'w')    #第一引数は保存したいファイルのパス。
#var5 = open('save.txt', 'w')    #txtファイルでも同様に操作できる
var5.write(var3) 
var5.close()    #close()を実行した時点で保存される。
#dumpsは文字列に変換するときに、下のように整形を含むこともできる。
#var3 = json.dumps(var2, sort_keys=True, indent=2)
```
###結果
jikkou4と同様のファイル出力が行われる。

#まとめ
jsonを読み書きするための関数は以下の通り、

```python:matome
#読み込みと変換
import json
var1 = open('test.json','r')   #jsonファイルを開く、第一引数はファイルパス
var2 = json.load(var1)         #jsonデータを辞書型で読み取る
var3 = json.dumps(var2)        #辞書型を文字列型に変換
var4 = json.loads(var3)        #文字列型を辞書型へ
#書き込みと保存
var5 = open('save.json', 'w')  #書き込みファイルを開く
json.dump(var2,var5)           #辞書型データを書き込み
var6 = open('saves.json', 'w') #書き込みファイルを開く
var6.write(var3)               #文字列型データを書き込み
var5.close()
var6.close()                   #ファイルを閉じて保存
```
loadとloads、dumpとdumpsはそれぞれ機能が違うので注意。
データの内容を書き換えたり、追加したりといった処理は#書き込みと保存の前に入れれば良さそう。
###おまけ
open()からclose()の処理はwith文で簡略化できる。

```python:omake
#書き込み部分にて
#var5 = open('save.json', 'w')
#json.dump(var2,var5)
#var5.close()
#だったのをwith文で
with open('save.json', 'w') as var5:
     json.dump(var2,var5)
```
これならclose()のし忘れを防げる。

#参考リンク
【参考１】[【Python入門】JSON形式データの扱い方](https://qiita.com/Morio/items/7538a939cc441367070d)