In python, how can I access the elements in the dictionary using access attributes?
In python, all elements in the dictionary are accessed through subscripts. However, in some ways, we can access the dictionary like accessing member variables:
A = {'foo': 1, 'bar': 2} print. fooprint. barsetattr and _ getattr _ use to see the following code: # coding: utf-8class Test (object): def _ init _ (self): self. a = 1self. B = 2 # def _ setattr _ (self, key, value): print '_ setattr __: % s' % keyself. _ dict _ [key] = value # _ getattr _ is called def _ getattr _ (self, key) only when a nonexistent member is accessed ): print '_ getattr __: % s' % keyreturn self. _ dict _ [key] if _ name _ = '_ main _': t = Test () print t. aprint t. bt. c = 12 print t. ct. c = 13t. a = 123 print t. d
Setattr is called every time an attribute is set, while _ getattr is called only when an element that does not exist is accessed. The attributes of the object are stored in the dict dictionary. The default setattr and getattr _ also access this dictionary. Access the dictionary through a Storage class package
#!/usr/bin/env python# coding: utf8import jsonclass Storage(dict): def __init__(self, *args, **kw): dict.__init__(self, *args, **kw) def __getattr__(self, key): return self[key] def __setattr__(self, key, value): self[key] = value def __delattr__(self, key): del self[key]if __name__ == '__main__': l = {'foo': 'bar'} s = Storage(l) print s.foo print s['foo']
We can see that, after packaging the Storage class, we can not only use the subscript s ['foo'], but also use s. foo to call the corresponding element of foo. The principle is very simple. We changed the default _ getattr and setattr implementations of Storage. The default implementation is to access the internal dict __, and this access is the base class dict, so access s. when foo is accessed, the internal dict ['foo'] is accessed, so elements can be accessed. For the use of the object_hook parameter in the loads json library, see the following code. The general json serialization and deserialization are as follows:
import jsonfrom decimal import *obj = {'name': 'haha', 'age': 23, 'height': 1.75}json_string = json.dumps(obj)print json_stringnew_obj = json.loads(json_string)print new_obj
We can see from the above that after dict is packaged, it can be transformed into Storage and accessed using access attributes. Json loads provides similar functions.
# coding: utf-8import jsonobj = {'name': 'haha', 'age': 23, 'height': 1.75}json_string = json.dumps(obj)from collections import namedtupleStudent = namedtuple('Student',['name', 'age', 'height'])def object_hook_handler(dict_obj):return Student(name=dict_obj['name'], age=dict_obj['age'], height=dict_obj['height'])new_obj = json.loads(json_string, object_hook=object_hook_handler)print new_obj
The printed result is: Student (name = u'hahaha', age = 23, height = 1.75). You can see that a function is input using the object_hook parameter to convert dict into a famous tuples. In python, classes can also be considered as a function, so you can directly input the class name as a parameter. From collections import OrderedDictnew_obj = json. loads (json_string, object_hook = OrderedDict) print new_obj: OrderedDict ([(u 'age', 23), (u 'name', u 'hahaha '), (u 'height', 1.75)]) Hide Storage for ease of use, it is best not to allow users to access Storage, so you can write like this:
#!/usr/bin/env python# coding: utf8import jsonclass Storage(dict): def __init__(self, *args, **kw): dict.__init__(self, *args, **kw) def __getattr__(self, key): return self[key] def __setattr__(self, key, value): self[key] = value def __delattr__(self, key): del self[key]def storage_object_hook(dct): return Storage(dct)def json_decode(data, *args, **kw): return json.loads(data, object_hook=storage_object_hook, *args, **kw)def json_encode(data, *args, **kw): return json.dumps(data, *args, **kw)if __name__ == '__main__': l = {'foo': 'bar'} l = json_decode(json_encode(l)) print l print l.foo