将名称空间与嵌套字典一起使用,在第二层有两个级别和两个键

Using namespace with nested dictionaries with two levels and two keys at second level

我有以下信息结构:

items= {i1: {ref: i1_ref, attrs: {attr1: 'red', attr2: 'low'}}, i2: {ref: i2_def, attrs: {attr1: 'green', attr2: 'hight'}}}

i1i2...都是字符串。

i1_ref, i2_ref...也是字符串。

我想要一个对象 i 来检索如下信息:

代码:

print(i.i1)
>>> i1_ref
print(i.i1.attrs)
>>> {attr1: 'red', attr2: 'low'}

将属性添加到 str 的子类以获得所需行为的解决方案。

items = {
    "i1": {"ref": "i1_ref", "attrs": {"attr1": 'red', "attr2": 'low'}},
    "i2": {"ref": "i2_def", "attrs": {"attr1": 'green', "attr2": 'hight'}}
}

# Subclass string, so we can add attributes to the instance.
class Item(str):
    def __new__(cls, d):
        s = super().__new__(cls, d["ref"])
        s.attrs = d["attrs"]
        return s

# Just a class that holds the dict keys as attributes
# and Item objects as their values.
class Items:
    def __init__(self, d):
        for it in d:
            setattr(self, it, Item(d[it]))

i = Items(items)
print(i.i1)
print(i.i1.attrs)

输出:

i1_ref
{'attr1': 'red', 'attr2': 'low'}

SimpleNamespace的不同解决方案:

from types import SimpleNamespace

items = {
    "i1": {"ref": "i1_ref", "attrs": {"attr1": 'red', "attr2": 'low'}},
    "i2": {"ref": "i2_def", "attrs": {"attr1": 'green', "attr2": 'hight'}}
}

class Item(SimpleNamespace):
    def __str__(self):
        return self.ref

i = SimpleNamespace(**{k:Item(**v) for k,v in items.items()})

print(i.i1)
print(i.i1.attrs)

尽管打印输出完全相同,但行为有点不同:
虽然第一个解决方案 中的 i.i1 实际上是一个字符串 (附加了 attrs),但第二个解决方案中的 i.i1 是一个 SimpleNamespace 字符串表示ref.
的对象 这意味着 i.i1 == "i1_ref" 对于第一个解决方案是 True,但是对于第二个解决方案,您需要编写 str(i.i1) == "i1_ref"i.i1.ref == "i1_ref".