Я огромный поклонник Python3’s Типы. SimplenAmespace.
. По сути, это позволяет нам принять дикт, как так:
my_dict = { "a": 1, "b": 2, "c": 3, } my_dict["a"] # 1 my_dict["b"] # 2, etc
И управлять этим так:
from types import SimpleNamespace my_namespace = SimpleNamespace(a=1, b=2, c=3) my_namespace.a # 1 my_namespace.b # 2 my_namespace.c # 3
В качестве альтернативы, мы также могли сделать что-то вроде:
from types import SimpleNamespace my_dict = { "a": 1, "b": 2, "c": 3, } my_namespace = SimpleNamespace(**my_dict) my_namespace.a # 1 my_namespace.b # 2 my_namespace.c # 3
Но – что происходит, если наше my_dict
вложен? Вот так:
my_dict = { "a": { "d": 4, }, "b": 2, "c": 3, "e": [5,6,7,{ "f": 8, }] } my_namespace = SimpleNamespace(**my_dict) my_namespace.a # {"d": 4} /womp womp 😭 my_namespace.a.d # raises Exception! 😭😭
Короче говоря, Simplenanamespace
Просто не поддерживает этот корпус использования. Но это нормально! Мы можем продлить Simplenanamespace
и построить эту функциональность для себя.
Определение рекурсивного пространства имен
from types import SimpleNamespace # this is how SimpleNamespace looks when output SimpleNamespace(**my_dict) # namespace(a={'d': 4}, b=2, c=3, e=[5, 6, 7, {'f': 8}]) class RecursiveNamespace(SimpleNamespace): @staticmethod def map_entry(entry): if isinstance(entry, dict): return RecursiveNamespace(**entry) return entry def __init__(self, **kwargs): super().__init__(**kwargs) for key, val in kwargs.items(): if type(val) == dict: setattr(self, key, RecursiveNamespace(**val)) elif type(val) == list: setattr(self, key, list(map(self.map_entry, val))) # this is how RecursiveNamespace looks when output RecursiveNamespace(**my_dict) # RecursiveNamespace( # a=RecursiveNamespace(d=4), # b=2, # c=3, # e=[5, 6, 7, RecursiveNamespace(f=8)])
Итак, что здесь происходит? Мы устанавливаем новый класс, RecursivenAmespace
это расширяется Simplenanamespace
Отказ В __init__
Метод конструктора, мы называем Simplenanamespace
Конструктор. Затем мы просто проходим через наш словарь и ценность, который является Также Словарь или список, мы создали то, что с RecursivenAmespace
Отказ ТА ДА.
Слияние
Технически мы даже не нужны Типы. Simplenanamespace
Здесь – мы можем реализовать этот класс без просто добавления двух строк кода:
class RecursiveNamespace2: # without extending SimpleNamespace! @staticmethod def map_entry(entry): if isinstance(entry, dict): return RecursiveNamespace(**entry) return entry def __init__(self, **kwargs): for key, val in kwargs.items(): if type(val) == dict: setattr(self, key, RecursiveNamespace(**val)) elif type(val) == list: setattr(self, key, list(map(self.map_entry, val))) else: # this is the only addition setattr(self, key, val)
Оригинал: “https://dev.to/taqkarim/extending-simplenamespace-for-nested-dictionaries-58e8”