标题可能有点难以描述。举个例子。我有一个配置文件。
CONFIG = {
'app_name': 'ZiXi',
'mysql': {
'host': '127.0.0.1',
}
'version': 'v2.0.11',
}
通常可以通过CONFIG['mysql']['host']
这种方式访问,但我们还是想更简单点访问。如
CONFIG.mysql.host
,那么有几种方法。
1. 通过新定义的dict子类,实现getattr等
参考这里 https://stackoverflow.com/questions/2352181/how-to-use-a-dot-to-access-members-of-dictionary
这个类有个缺陷,就是不能访问多层的
class Map(dict):
"""
Example:
m = Map({'first_name': 'Eduardo'}, last_name='Pool', age=24, sports=['Soccer'])
"""
def __init__(self, *args, **kwargs):
super(Map, self).__init__(*args, **kwargs)
for arg in args:
if isinstance(arg, dict):
for k, v in arg.iteritems():
self[k] = v
if kwargs:
for k, v in kwargs.iteritems():
self[k] = v
def __getattr__(self, attr):
return self.get(attr)
def __setattr__(self, key, value):
self.__setitem__(key, value)
def __setitem__(self, key, value):
super(Map, self).__setitem__(key, value)
self.__dict__.update({key: value})
def __delattr__(self, item):
self.__delitem__(item)
def __delitem__(self, key):
super(Map, self).__delitem__(key)
del self.__dict__[key]
使用示例:
m = Map({'first_name': 'Eduardo'}, last_name='Pool', age=24, sports=['Soccer'])
# Add new key
m.new_key = 'Hello world!'
# Or
m['new_key'] = 'Hello world!'
print m.new_key
print m['new_key']
# Update values
m.new_key = 'Yay!'
# Or
m['new_key'] = 'Yay!'
# Delete key
del m.new_key
# Or
del m['new_key']
2. pip安装dotmap来使用
pip install dotmap
使用很简单:
data = DotMap(jsonDict)
print(data.location.city)
但是,也有一个缺陷,如果访问的是变量就跪了,作者说自己去搞go了,不再投入改这个。
像这样field 如果是'mysql.host'是不行的:
def sysconf(field):
data = DotMap(jsonDict)
return data.field
3. 通过自定义的方法实现
参考 https://vinta.ws/code/dot-notation-obj-x-y-z-for-nested-objects-and-dictionaries-in-python.html
import functools
def nested_dict_get(dictionary, dotted_key):
keys = dotted_key.split('.')
return functools.reduce(lambda d, key: d.get(key) if d else None, keys, dictionary)
user_dict = {
'id': 123,
'username': 'vinta',
'settings': {
'enable_nsfw': True,
},
}
nested_dict_get(user_dict, 'username') # return 'vinta'
nested_dict_get(user_dict, 'settings.enable_nsfw') # return True
nested_dict_get(user_dict, 'settings.notification.new_follower') # return None
对这个进行改良了下:
def sysconf(field):
keys = field.split('.')
return functools.reduce(lambda d, key: d.get(key) if d else None, keys, CONFIG)
上面CONFIG是我的字典形式的配置项, 通过 sysconf('mysql.host')
即可取到 CONFIG['mysql']['host']
这个值了。