AutoDict与AutoOrderedDict
class DotDict(dict): # If the attribut is not found in the usual places try the dict itself def __getattr__(self, key): if key.startswith('__'): return super(DotDict, self).__getattr__(key) return self[key] class AutoDict(dict): _closed = False def _close(self): self._closed = True for key, val in self.items(): if isinstance(val, (AutoDict, AutoOrderedDict)): val._close() def _open(self): self._closed = False def __missing__(self, key): if self._closed: raise KeyError value = self[key] = AutoDict() return value def __getattr__(self, key): if False and key.startswith('_'): raise AttributeError return self[key] def __setattr__(self, key, value): if False and key.startswith('_'): self.__dict__[key] = value return self[key] = value class AutoOrderedDict(OrderedDict): _closed = False def _close(self): self._closed = True for key, val in self.items(): if isinstance(val, (AutoDict, AutoOrderedDict)): val._close() def _open(self): self._closed = False def __missing__(self, key): if self._closed: raise KeyError # value = self[key] = type(self)() value = self[key] = AutoOrderedDict() return value def __getattr__(self, key): if key.startswith('_'): raise AttributeError return self[key] def __setattr__(self, key, value): if key.startswith('_'): self.__dict__[key] = value return self[key] = value # Define math operations def __iadd__(self, other): if type(self) != type(other): return type(other)() + other return self + other def __isub__(self, other): if type(self) != type(other): return type(other)() - other return self - other def __imul__(self, other): if type(self) != type(other): return type(other)() * other return self + other def __idiv__(self, other): if type(self) != type(other): return type(other)() // other return self + other def __itruediv__(self, other): if type(self) != type(other): return type(other)() / other return self + other def lvalues(self): return py3lvalues(self)