下面的嵌套屬性字典(由柯特Hagenlocher的答案靈感的另一個實現剝離下來基本):
class AttrDict(dict):
""" Nested Attribute Dictionary
A class to convert a nested Dictionary into an object with key-values
accessibly using attribute notation (AttrDict.attribute) in addition to
key notation (Dict["key"]). This class recursively sets Dicts to objects,
allowing you to recurse down nested dicts (like: AttrDict.attr.attr)
"""
def __init__(self, mapping):
super(AttrDict, self).__init__()
for key, value in mapping.items():
self.__setitem__(key, value)
def __setitem__(self, key, value):
if isinstance(value, dict):
value = AttrDict(value)
super(AttrDict, self).__setitem__(key, value)
def __getattr__(self, item):
try:
return self.__getitem__(item)
except KeyError:
raise AttributeError(item)
__setattr__ = __setitem__
這個工作在兩個Python 2和3:
life = AttrDict({'bigBang': {'stars': {'planets': {}}}})
life['bigBang']['stars']['planets'] = {'earth': {'singleCellLife': {}}}
life.bigBang.stars.planets.earth.multiCellLife = {'reptiles': {}, 'mammals': {}}
print(life.bigBang.stars.planets.earth)
# -> {'singleCellLife': {}, 'multiCellLife': {'mammals': {}, 'reptiles': {}}}
轉換成KeyError異常在AttributeError的在__getattr__
Python3需要使得hasattr
作品也萬一屬性中沒有找到:
hasattr(life, 'parallelUniverse')
# --> False
'life.bigBang.stars.planets'定義一個'list',所以分配給它的'.earth'屬性將導致一個'AttributeError:'列表'對象沒有屬性'地球'。我猜你可能想要在'life'字典的定義中使用'{'planets':{}}''(如接受的答案所示)。 – martineau 2017-10-17 19:29:03