python - 使用 dicts 的 dict 创建命名空间
问题描述
目前我正在使用json
将字典保存到配置文件中。我加载它以将其转换为 adict
然后将其转换为 aSimpleNamespace
因为我更喜欢点符号来访问设置。为此,我加载它,如下例所示:
import json
from types import SimpleNamespace
SETTINGS = json.load(open("config.json", 'r'))
SETTINGS = SimpleNamespace(**SETTINGS)
但是,由于我当前正在将其加载dict
到 aSimpleNamespace
中,因此它不会在配置文件中加载子字典。例如,如果我这样做:
SETTINGS.server_info.port
我得到错误:
AttributeError: 'dict' object has no attribute 'port'
我想知道如何将所有字典作为名称空间加载到名称空间中,以便能够在字典中一直使用点表示法。
解决方案
没有必要对返回的数据递归地应用转换json.load
。您可以通过提供调用方法来简单地要求json.load
返回实例而不是字典。这个方法“将在每个 JSON 对象的解码结果被调用,并且它的返回值将被用来代替给定的.” (来自文档)。SimpleNamespace
object_hook
json.load
dict
最简单的object_hook
可能如下所示:
def dict_to_sns(d):
return SimpleNamespace(**d)
例如,给定以下输入:
{
"settings": {
"foo": {
"number": 4,
"size": "large"
},
"bar": {
"color": "orange",
"widgets": [
"gizmo",
"gadget",
"thing"
]
}
}
}
我们可以做到以下几点:
>>> 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']
推荐阅读
- c++ - While循环比较大小而不是数量
- lua - ZeroBrane 与 Lua 5.4
- python - 将数据转换为字典以进行发布请求
- flutter - Flutter/Dart - FutureBuilder bool 不返回 bool
- apache-spark - 读取xml时如何在spark数据框中包含元数据
- ios - 将字典中键的新值和先前值相加
- javascript - 无法获取 /ID (querystring) Express, nodeJS
- reactjs - 如何修复错误类型 void is not assignable to type ((event: MouseEvent
) => void) |未定义使用反应? - python - ModuleNotFoundError:没有名为“odata”Python 的模块
- class - 如何间接访问类的属性