Rya*_*fer 2 python dictionary python-3.x
目前,我正在使用json
将字典保存到配置文件。我将其加载以将其转换为a,dict
然后将其转换为a,SimpleNamespace
因为我更喜欢点符号来访问设置。为此,请按照以下示例加载它:
import json
from types import SimpleNamespace
SETTINGS = json.load(open("config.json", 'r'))
SETTINGS = SimpleNamespace(**SETTINGS)
Run Code Online (Sandbox Code Playgroud)
但是,由于我当前正在将加载dict
到,SimpleNamespace
因此未在配置文件内加载子命令。例如,如果我这样做:
SETTINGS.server_info.port
Run Code Online (Sandbox Code Playgroud)
我得到错误:
AttributeError: 'dict' object has no attribute 'port'
Run Code Online (Sandbox Code Playgroud)
我想知道如何将所有字典作为名称空间加载到命名空间中,以便在字典中一直使用点符号。
Mar*_*ers 11
您必须递归地将该SimpleNamespace
类应用于嵌套字典;我更喜欢在@functools.singledispatch()
这种情况下使用:
from functools import singledispatch
from types import SimpleNamespace
@singledispatch
def wrap_namespace(ob):
return ob
@wrap_namespace.register(dict)
def _wrap_dict(ob):
return SimpleNamespace(**{k: wrap_namespace(v) for k, v in ob.items()})
@wrap_namespace.register(list)
def _wrap_list(ob):
return [wrap_namespace(v) for v in ob]
Run Code Online (Sandbox Code Playgroud)
然后将其用作:
with open('config.json') as settings_file:
SETTINGS = wrap_namespace(json.load(settings_file))
Run Code Online (Sandbox Code Playgroud)
演示:
>>> SETTINGS = wrap_namespace({'foo': 'bar', 'ham': {'spam': 'eggs', 'monty': [{'name': 'Eric Idle'}]}})
>>> SETTINGS.foo
'bar'
>>> SETTINGS.ham.monty[0].name
'Eric Idle'
Run Code Online (Sandbox Code Playgroud)
不必将转换递归地应用于所返回的数据json.load
。您可以通过为调用提供一种方法来简单地要求json.load
返回SimpleNamespace
实例而不是字典。该方法“将被解码的每个JSON对象的结果调用,并将使用其返回值代替给定。” (来自docs)。object_hook
json.load
dict
最简单的object_hook
可能如下所示:
def dict_to_sns(d):
return SimpleNamespace(**d)
Run Code Online (Sandbox Code Playgroud)
例如,给出以下输入:
{
"settings": {
"foo": {
"number": 4,
"size": "large"
},
"bar": {
"color": "orange",
"widgets": [
"gizmo",
"gadget",
"thing"
]
}
}
}
Run Code Online (Sandbox Code Playgroud)
我们可以执行以下操作:
>>> import json
>>> from types import SimpleNamespace
>>> def dict_to_sns(d):
... return SimpleNamespace(**d)
...
>>> with open('settings.json') as fd:
... data = json.load(fd, object_hook=dict_to_sns)
...
>>> data
namespace(settings=namespace(bar=namespace(color='orange', widgets=['gizmo', 'gadget', 'thing']), foo=namespace(number=4, size='large')))
>>> data.settings.foo
namespace(number=4, size='large')
>>> data.settings.foo.number
4
>>> data.settings.bar.widgets
['gizmo', 'gadget', 'thing']
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
642 次 |
最近记录: |