跳转到主要内容

ChainMap的递归子类

项目描述

DeepChainMap

PyPI codecov pre-commit.ci status Code style: black

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 (5.1 kB 查看哈希值)

上传时间 源代码

构建分发

deep_chainmap-0.1.1-py3-none-any.whl (4.6 kB 查看哈希值)

上传时间 Python 3

由以下机构支持

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误日志 StatusPage StatusPage 状态页面