带路径的嵌套词典

texas的Python项目详细描述


https://img.shields.io/travis/numberoverzero/texas/master.svg?style=flat-squarehttps://img.shields.io/coveralls/numberoverzero/texas/master.svg?style=flat-squarehttps://img.shields.io/pypi/v/texas.svg?style=flat-squarehttps://img.shields.io/github/issues-raw/numberoverzero/texas.svg?style=flat-squarehttps://img.shields.io/pypi/l/texas.svg?style=flat-square

纯Python。路径键。类固醇链式地图。

安装

pip install texas

快速启动

import texas

context = texas.Context()

environment = context.include("environment")
cli = context.include("cli")

config = context.include("environment", "cli")

environment["src.root"] = "~/pics"
cli["src.type"] = "jpg"

config["src.root"]  # ~/pics
config["src.type"]  # jpg

# Change cli's root
cli["src.root"] = "~/other"

# Doesn't change the underlying environment root
environment["src.root"]  # ~/pics

# Modifies cli, which is the top context in config
del config["src.root"]
config["src.root"]  # ~/pics

# Snapshot the contexts into a single dict for use in modules that
# typecheck against dict (instead of collections.abc.Mapping)
import pprint
pprint.pprint(config.snapshot)
# {
#     "src": {
#         "root": "~/pics",
#         "type": "jpg"
#     }
# }

用法

上下文是带有(可配置)路径查找的命名空间python字典:

import texas

context = texas.Context()
# Single context
root = context.include("root")

# normal dictionary operations
root["foo"] = "bar"
assert "bar" == root["foo"]
del root["foo"]

# paths
root["foo.bar"] = "baz"
assert "baz" == root["foo.bar"]
del root["foo.bar"]

包括

include获取要加载到视图中的上下文名称的可变数目:

bottom = context.include("bottom")
top = context.include("top")

both = context.include("bottom", "top")

这可用于在查找值时创建优先级。顶部 上下文堆栈将首先检查键,然后检查下一个键,直到上下文 找到给定密钥:

bottom["key"] = "bottom"
assert both["key"] == "bottom"

top["key"] = "top"
assert both["key"] == "top"

结合路径,这对于配置管理来说非常强大:

context = texas.Context()
env = context.include("env")
cli = context.include("cli")
config = context.include("env", "cli")

env["src.root"] = "~/pics"
cli["src.type"] = "jpg"

assert config["src.root"] == "~/pics"
assert config["src.type"] == "jpg"

这甚至适用于单独的路径段,因为contextview返回 针对底层映射对象的代理:

config["src"]  # <texas.context.ContextView at ... >
config["src"]["type"]  # "jpg"

设置值仅适用于视图中的顶部上下文,因此 底部仍然相同:

assert bottom["key"] == "bottom"

它用可变的值分解-例如,这将修改列表 在下面的上下文中:

context = texas.Context() bottom = context.include(“bottom”) top = context.include(“top”) both = context.include(“bottom”, “top”)

bottom[“list”] = [] top[“list”].append(“modified!”)

assert bottom[“list”] == [“modified!”]

快照

上下文做了一些繁重的工作来使路径和多个指令一起工作 舒适地。不幸的是,有些库对isinstance进行检查 dict,而不是collections.abc.Mapping

当将ContextView传递给将执行许多 在一个紧密的循环中查找。因为对深度嵌套的 一组dict为每个级别创建一个代理(即。 {TT4}$为该值创建两个代理 something["foo.bar.baz"] = "blah")它可以显著加速到 “快照”或烘焙ContextView以获得更快的读取速度。

一般来说,合并dict最多是一个复杂的问题,有很多歧义。 为了简化操作,使用以下规则:

(1) For every key in each context, the top-most[0] context that contains
    that key will determine if the value will be used directly, or merged
    with other contexts.
(2) If that value is a collections.abc.Mapping, the value of that key in
    each context that contains that key will be merged.
    (A) If there is a context with that key whose value is NOT a mapping,
        its value will be ignored.
    (B) If that value is NOT a collections.abc.Mapping, the value will be
        used directly and no merging occurs[1].
3) These rules are applied recursively[2] for any nested mappings.

“包含该键的最上面的上下文”并不总是最上面的上下文。 在下面的示例中,底部上下文是唯一包含键的上下文 “底部”:

{
    "bottom": "bottom-value"
},
{
    "top": "top-value"
}

Snapshot:

{
    "bottom": "bottom-value",
    "top": "top-value"
}

当类型(映射,非映射)发生冲突时,最上面的上下文 确定类型。例如,这将从 底部和顶部,但不是中间(其值不是映射):

{
    "key": {
        "bottom": "bottom-value"
    }
},
{
    "key": ["middle", "non", "mapping"]
},
{
    "key": {
        "top": "top-value"
    }
}

Snapshot:

{
    "key": {
        "bottom": "bottom-value",
        "top": "top-value"
    }
}

当snapshot递归地将其规则应用于映射时,实现是 不是递归的。一个示例文件,它使用 与德克萨斯州相同的规则 here

上下文工厂

默认情况下,Texas使用简单的dict``s for storage.  However, this can be customized with the ``context_factory函数,例如使用 collections.OrderedDict或将值预加载到节点中。

此函数用于创建快照、上下文根、新上下文, 以及按路径设置值时的中间段。

created = 0

def factory():
    global created
    created += 1
    return dict()

# Root context container
context = texas.Context(context_factory=factory)
assert created == 1

# Including contexts
ctx = context.include("some-context")
assert created == 2

# Segments along a path when setting values
ctx["foo.bar"] = "value"
assert created == 3

内部

在内部,所有数据都存储在python dict中。你可以检查全球 上下文通过其contexts属性的状态:

import texas
context = texas.Context()

context.include("root.something.or.foo")
context.include("bar", "and.yet.another.foo", "finally")

print(context._contexts)

路径遍历由traverse函数执行,该函数只处理 遍历collestions.abc.Mapping。因此,当一个非映射值 在路径的末尾,路径应该按如下方式拆分:

full_path = "foo.bar.baz"
path, last = full_path.rsplit(".", 1)

assert path == "foo.bar"
assert last = "baz"

这允许我们遍历一个根并创建中间foobardict而不修改或检查baz

from texas.traversal import traverse, create_on_missing

root = dict()
full_path = "foo.bar.baz"
path, key = full_path.rsplit(".", 1)

node = traverse(root, path, ".", create_on_missing(dict))
node[key] = "value"

assert root["foo"]["bar"]["baz"] == "value"

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
手机上的html调试Java web应用程序   Java当前日期和过去日期之间的差值,以年、月、日、小时、分、秒为单位   如果方法名称相同,java如何使扩展类不从上面的类触发方法?   即使在提供了准确的firebase引用之后,java仍出现“无法跳转到类型”异常。请看详情   jar文件中的java图像   java如何避免从缓存读取时修改相同的对象实例?   Android中java完全控制的线程队列   JTextArea中的java计算   java如何独立运行。jar作为64位mashine上的32位   java在尝试实例化自引用泛型类的实例时,如何处理自引用类型参数   java如何安装着色jar而不是原来的jar   java在resultSet之后使用If-Else   多线程是java。朗,反思一下。方法调用线程安全   java 7语言向后兼容性   Objective C中的Category和Java 8中的Default方法是否等效?