将名称空间与嵌套字典一起使用,在第二层有两个级别和两个键
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'}}}
i1
、i2
...都是字符串。
i1_ref
, i2_ref
...也是字符串。
我想要一个对象 i
来检索如下信息:
i.i1
从 i1 获取 ref(i1_ref 值),i.i2
从 i2 获取参考(i2_ref 值)。
i.i1.attrs
从 i1 获取属性的嵌套字典,
i.i2.attrs
从 i2 获取属性的嵌套字典。
代码:
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"
.
我有以下信息结构:
items= {i1: {ref: i1_ref, attrs: {attr1: 'red', attr2: 'low'}}, i2: {ref: i2_def, attrs: {attr1: 'green', attr2: 'hight'}}}
i1
、i2
...都是字符串。
i1_ref
, i2_ref
...也是字符串。
我想要一个对象 i
来检索如下信息:
i.i1
从 i1 获取 ref(i1_ref 值),i.i2
从 i2 获取参考(i2_ref 值)。i.i1.attrs
从 i1 获取属性的嵌套字典,i.i2.attrs
从 i2 获取属性的嵌套字典。
代码:
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"
.