Proposal: SimpleNamespace "recursive" parameter
Marco Sulla
Marco.Sulla.Python at gmail.com
Fri Aug 14 00:39:58 EDT 2020
This seems to work:
from types import SimpleNamespace
from collections.abc import Iterable
def isIterableNotStr(arg):
return isinstance(arg, Iterable) and not isinstance(arg, str)
class DeepNamespace(SimpleNamespace):
def namespacesFromIterable(self, arg):
vals = []
changed = False
for x in arg:
not_iterable = True
try:
x.items
value = type(self)(**x)
changed = True
not_iterable = False
except AttributeError:
if isIterableNotStr(x):
value = self.namespacesFromIterable(x)
changed = True
not_iterable = False
if not_iterable:
value = x
vals.append(value)
if changed:
return tuple(vals)
return arg
def __init__(self, **kwargs):
super().__init__(**kwargs)
for k, v in kwargs.items():
try:
v.items
except AttributeError:
if isIterableNotStr(v):
self.__setattr__(k, self.namespacesFromIterable(v))
else:
self.__setattr__(k, type(self)(**v))
Notice that if the dict contains at any level an iterable that is not
a string or a dict-like object, this is converted to a tuple. Probably
there's a smarter way to maintain the original iterable type.
More information about the Python-list
mailing list