跳转到主要内容

自动激活任意嵌套的字典(`dict`)类。

项目描述

vivodict

https://img.shields.io/pypi/v/vivodict.svg https://img.shields.io/travis/somada141/vivodict.svg Documentation Status

此包提供了一种简单的自动激活 Python dict 的实现,即访问不存在的键不会引发标准的 KeyError 异常,而是隐式创建并返回一个空的自定义 dict

功能

  • 从标准 Python dict 类派生的自动激活 VivoDict 类(无第三方依赖)。

  • 任意嵌套 dict 对象的自动激活。

  • 方便的 flattenreplaceapply 操作方法。

  • 开源软件:MIT许可证

  • 文档:https://vivodict.readthedocs.io

动机

开发此包的主要动机是因为它包含了一段我一直在项目之间复制粘贴的代码。

我使用此代码的典型场景包括

  • 包装来自糟糕的API的解码JSON dict,这些API没有模式,只是决定丢弃值为 null 的键,导致代码中出现嵌套 if "key" in result:。这允许我在键存在时检索其值,或者至少在将它们不完整的数据映射到自己的数据结构时到达一个空 dict,该 dict 评估为 False

  • 创建任意嵌套的代码统计字典,我可以按照自己的喜好在代码中使用并保持组织,然后在发布到……嗯,Graphite之前快速扁平化到Graphite兼容的格式。

基本用法

这是在访问缺失键时典型的Python dict行为

>>> d = {"a": 1, "b": 2}
>>> d["a"]
1
>>> d["missing"]
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-3-d4f58b57b715> in <module>()
----> 1 d["missing"]

KeyError: 'missing'

而如果我们使用VivoDict,则在访问缺失键时,我们会提供一个隐式创建的空VivoDict,如下所示

>>> from vivodict import VivoDict
>>> d = VivoDict.vivify({"a": 1, "b": 2})
>>> d["a"]
1
>>> d["missing"]
{}

现在,虽然上述内容似乎没有提供简单try-exceptif "key" not in d所提供的内容,但VivoDict在处理可能存在多个级别缺失键的任意嵌套字典时变得很有用。例如

>>> from vivodict import VivoDict
>>> d = VivoDict({"a": 1, "b": {"c": 2}, "d": {"e": {"f": 3}}})
>>> d["a"]
1
>>> d["b"]["c"]
2
>>> d["d"]["e"]["f"]
3
>>> d["i"]["am"]["missing"]["eh"] = 4
>>> d
{'a': 1,
'b': {'c': 2},
'd': {'e': {'f': 3}},
'i': {'am': {'missing': {'eh': 4}}}}

因此,正如所见,自动激活化允许用户将键和值嵌套到任何程度。

便利函数

除了上述内容之外,VivoDict类中还内置了一些基本的便利方法,主要是因为它们使我的生活更轻松、更懒惰。

flatten

正如之前提到的,我使用vivodict的典型用例之一是将其用于存储嵌套指标,然后通过简单的HTTP请求将它们发布到Graphite。

然而,Graphite的结构基于.分隔的名称,其中任何在.之前的内容都被认为是指标文件夹,最后一个标记是指标本身。

因此,我需要一个快速将嵌套dict扁平化为Graphite兼容版本的方法。

flatten方法正是这样做的。

>>> d = VivoDict.vivify({"a": 1, "b": {"c": 2}, "d": {"e": {"f": 3}}})
>>> d.flatten()
{'a': 1, 'b.c': 2, 'd.e.f': 3}

replace

遵循与flatten相同的原理,我需要在发布周期之间快速“重置”我的指标回到0。

因此,replace将用给定的value替换树中所有“叶节点”的值。

>>> d = VivoDict.vivify({"a": 1, "b": {"c": 2}, "d": {"e": {"f": 3}}})
>>> d.replace(replace_with=0)
>>> d
{'a': 0, 'b': {'c': 0}, 'd': {'e': {'f': 0}}}

如果您需要保留原始副本,我建议您使用copy包及其deepcopy函数(因为Python按引用传递)如下所示

>>> import copy
>>> original = VivoDict.vivify({"a": 1, "b": {"c": 2}, "d": {"e": {"f": 3}}})
>>> modified = copy.deepcopy(original)
>>> modified.replace(replace_with=0)
>>> original
{'a': 1, 'b': {'c': 2}, 'd': {'e': {'f': 3}}}
>>> modified
{'a': 0, 'b': {'c': 0}, 'd': {'e': {'f': 0}}}

apply

最后,我经常需要通过给定函数修改所有值,通常是除以观察次数以获得平均值,这可以通过apply方法轻松完成,该方法可以接受任何callable作为参数,并用其返回值替换原始值

>>> d = VivoDict.vivify({"a": 1, "b": {"c": 2}, "d": {"e": {"f": 3}}})
>>> def double(value):
>>>     return value * 2
>>> d.apply(double)
>>> d
{'a': 2, 'b': {'c': 4}, 'd': {'e': {'f': 6}}}
>>> d.apply(lambda value: value / 2)
{'a': 1, 'b': {'c': 2}, 'd': {'e': {'f': 3}}}

历史

0.3.1 (2017-07-23)

  • README.rst: 修复了格式上的小错误。

0.3.0 (2017-07-23)

  • 清理文档并删除了大量不必要的材料。

0.2.0 (2017-07-23)

  • 添加了更多单元测试并改进了文档字符串。

0.1.1 (2017-07-23)

  • 修复了Python依赖项的问题。

0.1.0 (2017-07-23)

  • 首次发布到PyPI。

项目详情


下载文件

下载适用于您平台的文件。如果您不确定选择哪个,请了解更多关于 安装包 的信息。

源代码分发

vivodict-0.3.1.tar.gz (14.8 kB 查看哈希值)

上传时间 源代码

构建分发

vivodict-0.3.1-py2.py3-none-any.whl (10.3 kB 查看哈希值)

上传时间 Python 2 Python 3