Pythonでdictionaryを扱う時に便利なライブラリ「Box」の紹介です。
Pythonのディクショナリとは ' Key : Value ペアの配列 ' ですが、
このような配列の概念は数多くの言語に標準で用意されています。
( * PHP => 連想配列, Java => HashMap ... etc )
# Dictionaryの例
val = {"name": "Michel", "age": 34, "city": "New York"}
print(val['city']) # output: New York
ディクショナリの値にアクセスには ブラケット
*[] 内に 配列のkey名を入れて値を取り出しますが、
配列の階層が深いとブラケットの連続になってしまいます。
# 階層が深いdictの値を取り出す例
print(data['movies']['Spaceballs']['stars'][2]['name'])
そんな階層が深いディクショナリの扱いを
少し楽にしてくれそうな Python用のライブラリが「Box
」です。
Boxを使うと下記のように ドット形式でdictonaryの値にアクセスすることができるようになります。
# boxを使ってdictionaryにアクセス
data.movies.Spaceballs.stars[2].name
# 通常のアクセスの仕方
# data['movies']['Spaceballs']['stars'][2]['name']
・Boxを使うとオブジェクトと同じように ドット形式でディクショナリの値にアクセスできる
Boxはpipパッケージで提供されているので、
コマンドライン上から"pipコマンド
"を使ってインストールします。
# pipコマンドからBOXの導入
pip install python-box
# python3
# pip3 install python-box
# boxの呼び出し
from box import Box
Boxの使い方は簡単で dictionaryデータをBoxオブジェクトでラップするだけで、
ドット形式でアクセスすることができます。
from box import Box
# dictionary
users = {"name": "Michel", "age": 34, "city": "New York"}
# 変数'user_box'内でBoxオブジェクトの作成
user_box = Box(users)
print(user_box.name) # Michel
Boxは Boxクラスをインスタンス化した時に、
ディクショナリデータをオブジェクトに変換するライブラリなので、
下記の様な階層が深めの場合でも コードが書きやすくなります。
( * ディクショナリ変数は新たにコピーされて作成されるので、オリジナルデータは変更されません )
from box import Box
data = {
"movies": {
"Spaceballs": {
"imdb stars": 7.1,
"rating": "PG",
"length": 96,
"director": "Mel Brooks",
"stars": [
{"name": "Mel Brooks", "imdb": "nm0000316",
"role": "President Skroob"},
{"name": "John Candy", "imdb": "nm0001006", "role": "Barf"},
{"name": "Rick Moranis", "imdb": "nm0001548",
"role": "Dark Helmet"}
]
}
}
}
# インスタンス化
mbox = Box(data)
# 普通にディクショナリを扱う場合
# y = data['movies']['Spaceballs']['stars']
# boxで扱う場合
z = mbox.movies.Spaceballs.stars
# forループでアクセスする場合
for x in z:
# print(x['name']) # 通常のディクショナリの場合
print(x.name) # boxの場合
上記の例ではPythonのDictionaryからBoxオブジェクトを作成しましたが、
JSONデータを直接読み込むことも可能です。
( yamlから読み込む場合は ' ruamel.yaml
' 又は ' PyYaml
' が導入されている必要があります )
from box import Box
# JSONデータ
json = '{ "name":"John", "age":31, "city":"New York" }'
# jsonデータを読み込む場合は'from_json'を使います *ファイルからも読み込み可能
user = Box.from_json(json)
# user = Box.from_yaml(somedata) * yamlを読み込む場合
print(user.name) # John
Boxでインスタンス化したオブジェクトは
ディクショナリやJSONにも変換出来るメソッドが用意されています。
from box import Box
# dictionary
users = {"name": "Michel", "age": 34, "city": "New York"}
user_box = Box(users)
user_box.to_dict() # dictionaryに変換
user_box.to_json() # JSONに変換
以上がBoxのでした。
DjangoやFlaskのWebフレームワークでテンプレートに変数を渡す時に
Boxを使って配列をドット形式でアクセス出来るように統一したりと
色々と活躍する場面が多そうです。
GitHub : cdgriffith/Box