简体   繁体   English

如何创建一个带有不可变变量的 python 字典,这些变量正在改变?

[英]How can I create a python dict with immutable variables, that are changing?

I would like to have a dictionary like this one:我想要一本这样的字典:

primary = "#efefef"

style = {
    "H2": {
        "text-align": "center",
        "color": primary
    }
}

or even better connected dictionaries like these:甚至更好的连接字典,例如:

colors = {
    "primary" : "#efefef"
}

styles = {
    "H2": {
        "text-align": "center",
        "color": colors["primary"]
    }
}

How can I connect the style dict with the variable primary or the dict colors, so that the dict style changes if primary or colors get new values?如何将样式 dict 与变量 primary 或 dict colors 连接起来,以便在 primary 或 colors 获得新值时改变 dict 样式?

You can use collections.ChainMap to create a mapping that relies on other dicts.您可以使用collections.ChainMap创建依赖于其他字典的映射。 This works if the relevant keys are the same, so you can use it to solve your first case:如果相关键相同,则此方法有效,因此您可以使用它来解决您的第一种情况:

from collections import ChainMap

primary = {"color": "#efefef"}
style = {
    "H2": ChainMap({"text-align": "center"}, primary),
}

print(style)
primary["color"] = "#000000"
print(style)

Which gives the following output:这给出了以下 output:

{'H2': ChainMap({'text-align': 'center'}, {'color': '#efefef'})}
{'H2': ChainMap({'text-align': 'center'}, {'color': '#000000'})}

The second case can be solved with custom dict classes to defer the __getitem__ call:第二种情况可以通过自定义 dict 类来解决,以推迟__getitem__调用:

from collections import UserDict
    

class LazyDict(UserDict):
    def __getitem__(self, key):
        return LazyItem(self.data, key)


class LazyItem:
    def __init__(self, mapping, key):
        self.mapping = mapping
        self.key = key

    @property
    def value(self):
        return self.mapping[self.key]


class EagerDict(dict):
    def __getitem__(self, key):
        obj = super().__getitem__(key)
        if isinstance(obj, LazyItem):
            return obj.value
        return obj


colors = LazyDict({
    "primary" : "#efefef",
})
styles = {
    "H2": EagerDict({
        "text-align": "center",
        "color": colors["primary"],
    }),
}

print(styles["H2"]["color"])
colors["primary"] = "#000000"
print(styles["H2"]["color"])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM