ChainMap的递归子类
项目描述
DeepChainMap
是collections.ChainMap
的递归子类。
安装
pip install deep-chainmap
用法
collections.ChainMap
的典型用法是从分层映射(基本上是字典)源聚合配置数据。然而,它不适用于非平坦(嵌套)映射,因为查找机制只适用于映射的最顶层。
deep_chainmap.DeepChainMap
通过在任意深度嵌套的映射中进行递归查找,提供了一个简单的解决方案。让我们用一个简单的例子来说明这一点。我们将模拟3层映射,并假装它们来自不同的来源(默认配置、配置文件和运行时配置的参数)。
from deep_chainmap import DeepChainMap
default_layer = {
"architecture": "gpu",
"logging_level": "warning",
"solver": "RK4",
"database": {
"url": "unset",
"keep_in_sync": False,
},
"mesh": {
"type": "rectangular",
"resolution": {
"x": {
"npoints": 100,
"spacing": "linear",
},
"y": {
"npoints": 100,
"spacing": "linear",
},
"z": {
"npoints": 100,
"spacing": "linear",
},
},
},
}
config_file_layer = {
"architecture": "cpu",
"mesh": {
"resolution": {
"x": {
"spacing": "log",
},
"z": {
"npoints": 1,
},
},
},
}
runtime_layer = {
"logging_level": "debug",
"database": {
"url": "https://my.database.api",
"keep_in_sync": True
},
}
# now building a DeepChainMap
cm = DeepChainMap(runtime_layer, config_file_layer, default_layer)
现在当请求单个参数时,它将按插入顺序在每个层中查找,直到找到值。在这里,runtime_layer
优先于config_file_layer
,而config_file_layer
又优先于default_layer
。
>>> cm["logging_level"]
'debug'
>>> cm["mesh"]["resolution"]["x"]["spacing"]
'log'
>>> cm["mesh"]["resolution"]["x"]["npoints"]
100
请注意,任何层的子映射都可以作为新的DeepChainMap
实例检索
>>> cm["mesh"]
DeepChainMap({'resolution': {'x': {'spacing': 'log'}, 'z': {'npoints': 1}}},
{'resolution': {'x': {'npoints': 100, 'spacing': 'linear'},
'y': {'npoints': 100, 'spacing': 'linear'},
'z': {'npoints': 100, 'spacing': 'linear'}},
'type': 'rectangular'})
另一个重要功能是to_dict
方法,它从DeepChainMap
构建内置的dict
>>> cm.to_dict()
{
'architecture': 'cpu',
'logging_level': 'debug',
'solver': 'RK4',
'database': {
'url': 'https://my.database.api',
'keep_in_sync': True
},
'mesh': {
'type': 'rectangular',
'resolution': {
'x': {'npoints': 100, 'spacing': 'log'},
'y': {'npoints': 100, 'spacing': 'linear'},
'z': {'npoints': 1, 'spacing': 'linear'}
}
}
}
一个重要的影响是,DeepChainMap
类使得深度优先字典合并算法的简单、功能实现成为可能
from deep_chainmap import DeepChainMap
def depth_first_merge(*mappings) -> dict:
return DeepChainMap(*mappings).to_dict()
限制
作为标准 collections.ChainMap
类,DeepChainMap
设计上不执行任何数据验证。相反,它假定输入映射的结构相似,这意味着将一个键映射到某个输入映射中的一个字典的映射,也被假定为映射到其他所有输入映射中的字典实例。请使用优秀的 schema 库或类似项目来完成此任务。
:warning: 与 collections.ChainMap
的重要区别是,当在 DeepChainMap
实例中设置一个 (键,值) 对时,新值将存储在第一个 已包含父映射的映射 中。例如,如果我们运行
>>> cm["mesh"]["resolution"]["x"]["spacing"] = "exp"
受影响的层是 config_file_layer
而不是 runtime_layer
,如我们所见
>>> config_file_layer
{
'architecture': 'cpu',
'mesh': {
'resolution': {
'x': {'spacing': 'exp'},
'z': {'npoints': 1}
}
}
}
>>> runtime_layer
{
'logging_level': 'debug',
'database': {
'url': 'https://my.database.api',
'keep_in_sync': True
}
}
这种行为是实现细节的副作用,并且可能在未来的版本中发生变化。请勿依赖它。
项目详情
deep_chainmap-0.1.1.tar.gz 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | e8aeddc81e62433cf0de55cb714d74495b221d9f92017873f434829189cf4000 |
|
MD5 | 1f351496910cfcabb639a09f537f3fa2 |
|
BLAKE2b-256 | 187571d603422a83e2d501703395127f4f0d1c0d10cb7d22557b01804518ed0c |
deep_chainmap-0.1.1-py3-none-any.whl 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | b37aa50122ffbb5406180eb16c32e42ac29ee4b9c7b8d5b22a002073976c0bff |
|
MD5 | 464c3a1bd0b56f5a7b4ac0ee2b2dd734 |
|
BLAKE2b-256 | 2ae4ca4710a2a2828404ba928c8c456759a32cc230d37dfc2432ec88506cddaf |