Python использует dict со значениями-типами str, int, attribute и nested attribute в другом модуле - PullRequest
0 голосов
/ 24 августа 2018

У меня есть модуль (module2), который содержит одну функцию:

#module2
def get_items():
    return {'thing1': 'string_value',
            'thing2': 1,
            'thing3': 'self.foo1',
            'thing4': 'self.foo2.bar',
            'thing5': 'self.foo3.bar['some_key']'} 

Как видно, ключи словаря являются строками, значения включают в себя строки и целые числа, но также атрибуты (т. Е. self.foo1), вложенные атрибуты (т. Е. self.foo2.bar) и ссылки dict внутри вложенного атрибута (т. Е. * 1006). *) написано в виде строк. Они написаны как строки, потому что в контексте module2 нет self, скорее я бы хотел импортировать этот словарь в другой модуль (module1) и сослаться на некоторое self.

Мне известно, что я могу получить доступ к атрибутам через getattr(self, value.split('self.')[1]. Я настроил рекурсивную функцию для получения вложенных атрибутов, которая в приведенном ниже коде называется «rgetattr».

Единственное, что я не могу понять, это как обращаться с вложенным словарем.

Конкретно, мне бы хотелось следующее поведение:

#module2
def get_items():
    return {'thing1': 'string_value',
            'thing2': 1,
            'thing3': 'self.foo1',
            'thing4': 'self.foo2.bar',
            'thing5': 'self.foo3.bar['some_key']'} 

#module1
Class my_class:
    def __init__(self, foo):
        self.foo = foo # Note that this foo is an object

        ### The following is how I would like the imported dictionary to look ###
        my_desired_dict = {'thing1': 'string_value',
                           'thing2': 1,
                           'thing3': self.foo1,
                           'thing4': self.foo2.bar
                           'thing5': self.foo3.bar['some_key']}

        ### The following is how I am attempting to achieve this ###
        import module2
        item_dict = module2.get_items()

        my_desired_dict = {}

        for i in item_dict:
            if type(item_dict[i])==str and item_dict[i].startswith('self.'):
                    variable = item_dict[i].split('self.')[1]
                    this_attr = rgetattr(self, variable)
            else:
                 this_attr = item_dict[i]
            my_desired_dict[i] = this_attr



    def rgetattr(obj, attr, *args):
        def _getattr(obj, attr):
            return getattr(obj, attr, *args)
        return functools.reduce(_getattr, [obj] + attr.split('.'))

Я был бы открыт к изменению «строк ссылок на атрибуты» в module2 на простой self.foo и т. Д., Если бы был способ сделать это без запуска NameError.

...