2015/09/02更新

[Python] JSONを扱う

このエントリーをはてなブックマークに追加      

こんにちは、@yoheiMuneです。
Pythonを使い始めて2ヶ月、仕事でもプライベートでも色々な実装をしていますが、基礎部分が不足していて調べる時間が多い・・・。しっかりと基礎を固めるべく、Pyhtonと向き合いたいと思います。
今日はその中で、jsonパッケージを使ったJSONの扱いをブログに書きます。

画像


目次




jsonパッケージについて

jsonパッケージを用いることで、Pythonの辞書オブジェクト->JSON文字列、JSON文字列->Pythonの辞書オブジェクトに変換することができます。最近では多くのAPIがJSONでのやり取りをしているので、JSONの取り扱いは必須ですね。
以下はjsonパッケージの公式リファレンスです。

Python2系
- http://docs.python.jp/2.7/library/json.html

Python3系
- http://docs.python.jp/3.4/library/json.html


それぞれのバージョンのリファレンスを掲載しましたが、扱い方は同じのようです。



JSON文字列 -> Pythonオブジェクト

まずはJSON文字列からPythonオブジェクトに変換するところです。この機能には2つの関数が存在します。

  • loads関数:文字列からPythonオブジェクトに変換する
  • load関数:ファイルオブジェクトからPythonオブジェクトに変換する

loads関数(文字列 -> Pythonオブジェクト)

Python2系

jsonString = '''
{
    "name": "aaa",
    "age": 30
}
'''
data = json.loads(jsonString)
print(data) # {u'age': 30, u'name': u'aaa'}
print(data["name"]) # aaa

# 日本語が含まれる場合
jsonString = '''
{
    "name": "あああ",
    "age": 30
}
'''
data = json.loads(jsonString)
print(data) # {u'age': 30, u'name': u'\u3042\u3042\u3042'}
print(data["name"]) # あああ

Python3系

jsonString = '''
{
    "name": "aaa",
    "age": 30
}
'''
data = json.loads(jsonString)
print(data) # {'name': 'aaa', 'age': 30}
print(data["name"]) # aaa

# 日本語が含まれる場合
jsonString = '''
{
    "name": "あああ",
    "age": 30
}
'''
data = json.loads(jsonString)
print(data) # {'name': 'あああ', 'age': 30}
print(data["name"]) # あああ


load関数(ファイルオブジェクト -> Pythonオブジェクト)

Python2系

# "user1.json"
# {
#     "name": "bbb",
#     "age": 20  
# }
f = open("user1.json")
data = json.load(f)
print data # {u'age': 20, u'name': u'bbb'}
print data["name"] # bbb

# "user2.json"
# {
#     "name": "いいい",
#     "age": 20  
# }
f = open("user2.json")
data = json.load(f)
print(data) # {u'age': 20, u'name': u'\u3044\u3044\u3044'}
print(data["name"]) # いいい

Python3系

# "user1.json"
# {
#     "name": "bbb",
#     "age": 20  
# }
f = open("user1.json")
data = json.load(f)
print data # {'name': 'bbb', 'age': 20}
print data["name"] # bbb

# "user2.json"
# {
#     "name": "いいい",
#     "age": 20  
# }
f = open("user2.json")
data = json.load(f)
print(data) # {'name': 'いいい', 'age': 20}
print(data["name"]) # いいい



Pythonオブジェクト -> JSON文字列

続いてPythonオブジェクトからJSON文字列に変換するところです。こちらも同じく2つの関数が存在します。

  • dumps関数:PythonオブジェクトをJSON文字列に変換する
  • dump関数:PythonオブジェクトをJSON形式でファイルに書き込む

dumps関数(Pythonオブジェクト -> JSON文字列)

Python2系、3系で共通

dict = {
    "name": "aaa",
    "age": 30
}
jsonstring = json.dumps(dict)
print(jsonstring) # {"age": 30, "name": "aaa"}

# 日本語が含まれる場合(ensure_ascii=Falseを指定する)
dict = {
    "name": "あああ",
    "age": 30
}
jsonstring = json.dumps(dict, ensure_ascii=False)
print(jsonstring) # {"age": 30, "name": "あああ"}

dump関数(Pythonオブジェクト -> ファイル書き込み)

Python2系、3系で共通

dict = {
    "name": "aaa",
    "age": 30
}
f = open("output.json", "w")
json.dump(dict, f) # output.jsonの中身は、{"age": 30, "name": "aaa"}

# 日本語が含まれる場合(ensure_ascii=Falseを指定する)
dict = {
    "name": "あああ",
    "age": 30
}
f = open("output2.json", "w")
json.dump(dict, f, ensure_ascii=False) # output2.jsonの中身は、{"age": 30, "name": "あああ"}



json.dump[s]の便利なオプション

JSON文字列を生成する際に以下のように幾つかの便利な機能が存在します。

出力内容を整形する

indentを指定することでJSON出力を整形することができます。

Python2系、3系で共通

dict = {
    "name": "aaa",
    "age": 30
}
jsonstring = json.dumps(dict, indent=2)
print(jsonstring)
# {
#   "age": 30,
#   "name": "aaa"
#}

プロパティ名でソートする

sort_keysを指定することで、JSONでプロパティが並ぶ場合に、プロパティ名でソートした結果を出力することができます。

Python2系、3系で共通

dict = {
    "c": 1,
    "b": 2,
    "a": 3
}
print(json.dumps(dict, sort_keys=True, indent=2))
# {
#   "a": 3, 
#   "b": 2, 
#   "c": 1
# }

セパレーターを指定する

separatorsを指定することで、JSON内の,:を別のセパレーターに変更することもできます。

Python2系、3系で共通

dict = {
    "a": 1,
    "b": 2
}
print(json.dumps(dict, separators=("*", "="), indent=2))
# {
#   "a"=1*
#   "b"=2
# }

値の操作を行う

object_hookを用いることでdictの代わりにobject_hookに指定した関数の戻り値を受け取ることができます。
def as_complex(dct):
    if '__complex__' in dct:
        return complex(dct['real'], dct['imag'])
    return dct
jsonstring = '''
{
    "__complex__": true, 
    "real": 1, 
    "imag": 2
}
'''
print(json.loads(jsonstring, object_hook=as_complex)) # (1+2j)



最後に

Pythonは色々と楽に書けて便利ですが、基本を学んでいないと調べる手間ばかり増えて大変ですね。次回以降もPythonについてブログを何か書けたらと思います。

最後になりますが本ブログでは、フロントエンドのネタやPythonネタを中心に情報を発信しています。気になった方はぜひ、RSSTwitterをフォローして頂けますと幸いです ^ ^。

最後までご覧頂きましてありがとうございました!





こんな記事もいかがですか?

RSS画像

もしご興味をお持ち頂けましたら、ぜひRSSへの登録をお願い致します。