62 lines
1.8 KiB
Python
62 lines
1.8 KiB
Python
# DotDict For Config. Case Insensitive.
|
||
|
||
class DotDict(dict):
|
||
def __init__(self, name, *args, **kwargs):
|
||
super().__init__(*args, **kwargs)
|
||
self["name"] = name
|
||
|
||
def __getattr__(self, attr):
|
||
attr = attr.lower() # case insensitive
|
||
if attr in self:
|
||
return self[attr]
|
||
else:
|
||
raise AttributeError(f"'{self.__class__.__name__}-{self.name}' has no attribute '{attr}'")
|
||
|
||
def __setattr__(self, attr, value):
|
||
attr = attr.lower() # case insensitive
|
||
if attr not in self:
|
||
raise AttributeError(f"'{self.__class__.__name__}-{self.name}' has no attribute '{attr}'")
|
||
self[attr] = value
|
||
|
||
def __delattr__(self, attr):
|
||
attr = attr.lower() # case insensitive
|
||
if attr in self:
|
||
del self[attr]
|
||
else:
|
||
raise AttributeError(f"{self.__class__.__name__}-{self.name} object has no attribute '{attr}'")
|
||
|
||
@classmethod
|
||
def from_dict(cls, d, name):
|
||
if not isinstance(d, dict):
|
||
return d
|
||
|
||
dot_dict = cls(name)
|
||
for key, value in d.items():
|
||
key = key.lower() # case insensitive
|
||
if isinstance(value, dict):
|
||
dot_dict[key] = cls.from_dict(value, key)
|
||
else:
|
||
dot_dict[key] = value
|
||
if dot_dict[key] == "True": # Fuck! Json has no bool type!
|
||
dot_dict[key] = True
|
||
if dot_dict[key] == "False":
|
||
dot_dict[key] = False
|
||
if dot_dict[key] == "None":
|
||
dot_dict[key] = None
|
||
return dot_dict
|
||
|
||
|
||
if __name__ == '__main__':
|
||
nested_dict = {
|
||
"a": 1,
|
||
"b": {
|
||
"c": 2,
|
||
"ACDeef": {
|
||
"e": 3
|
||
}
|
||
}
|
||
}
|
||
|
||
dd = DotDict.from_dict(nested_dict, "root")
|
||
print(dd.b.acdeef.e) # 输出:3
|