38
35

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Python dictに対しAttributeでアクセスできるようにする

Last updated at Posted at 2014-10-01

動機

Pythonでは、JavaScriptなどとは異なりディクショナリ要素に対しAttributeでアクセスすることはできない。
つまり、dict_obj["value"]はOKだがdict_obj.valueとはできない。

これで不便を感じるのは、Jsonデータを扱う際だ。なんといってもJavaScript側ではAttributeでアクセスできるので、同じように書きたいというのが人情である。

そんなわけで、dict(今回はJsonオブジェクトを想定)に対しAttributeでアクセスする方法を紹介する。

実装

Pythonでは、Jsonをloadすると、ディクショナリになる。

>>> import json
>>> json.loads('{"v1":"xxxx", "v2":"vvvv"}')
{'v1': 'vvvv', 'v2': 'xxxx'}

前述したとおり、アクセスする際はobj["v1"]という形になりobj.viはNGになる。

これを解決する一番簡単な方法はattrdictというライブラリを使ってしまうことだ。

ただ、わざわざインストールするのがちょっと、という場合は以下のような簡易な方法が使える。
json.loadsを行う際に、object_hookを利用し各オブジェクトを属性アクセスを実装(__getattr__)したクラスでラップするようにする。これで、Attribute経由で要素にアクセスできるようになる。

import json

class AttributeDict(object):
    def __init__(self, obj):
        self.obj = obj

    def __getstate__(self):
        return self.obj.items()

    def __setstate__(self, items):
        if not hasattr(self, 'obj'):
            self.obj = {}
        for key, val in items:
            self.obj[key] = val

    def __getattr__(self, name):
        if name in self.obj:
            return self.obj.get(name)
        else:
            return None

    def fields(self):
        return self.obj

    def keys(self):
        return self.obj.keys()

if __name__ == "__main__":
    attribute_json = json.loads('{"v1":"xxxx", "v2":"vvvv"}', object_hook=AttributeDict)
    print("attribute_json.v1 = {0}".format(attribute_json.v1))

    json_with_array = json.loads('{"arr":[{"v":"xxxx"}, {"v":"vvvv"}]}', object_hook=AttributeDict)
    print("json_with_array[0].v = {0}".format(json_with_array.arr[0].v))

実行結果

attribute_json.v1 = xxxx
json_with_array[0].v = xxxx

Attributeアクセスができるとコードの補完もきくようになるので、実装しやすくなる。お試しされたし。

参考

attrdict
using JSON keys as python attributes in nested JSON
soundcloud-python/resource.py
Sample on Gist

38
35
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
38
35

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?