Динамическое получение метаинформации о классах Python, объявленных в модуле / скрипте - PullRequest
0 голосов
/ 01 октября 2018

У меня есть набор классов, которые я хотел бы иметь возможность динамически инициализировать из dict.

class A(object):
    var = 1

class B(object):
    val = 2

class C(object):
    var = 1
    val = 3

BASE = {'a': A, 'b': B, 'c': C}

Я мог бы использовать их в некоторых динамических функциях, таких как

def create_and_obtain(kind, **kwargs):
    base = BASE[kind]()
    for kwarg in kwargs.keys():
        print(getattr(base, kwarg))
>>> create_and_obtain('c', var=None, val=None)
1
3

Если у меня есть много классов, которые время от времени добавляются, изменяются и удаляются, я должен следить за тем, чтобы мой BASE обновлялся.Есть ли способ динамического построения BASE в соответствии с заявленными классами в скрипте?Могут ли сами классы иметь какие-либо добавленные meta_attributes, которые можно использовать для расширения определения BASE за пределы этого упрощенного примера?

Например, можно ли добавить некоторые метатеги, например:

class A(object):
    ...
    _meta_dict_key_ = 'apples'
class B(object):
    ...
    _meta_dict_key_ = 'bananas'
class C(object):
    ...
    _meta_dict_key_ = 'coconuts'

так что BASE динамически построен как:

BASE = {'apples': A, 'bananas': B, 'coconuts':C} 

Ответы [ 2 ]

0 голосов
/ 01 октября 2018

В Python есть декораторы классов, и поэтому чистый путь может быть таким:

BASE = {}

def register(klass):  # Uses an attribute of the class
    global BASE
    BASE[klass.name] = klass
    return klass

def label(name):  # Provide an explicit name
    def deco(klass):
        global BASE
        BASE[name] = klass
        return klass
    return deco

@register
class A(object):
    var = 1
    name = 'bananas'

@label('apples')
class B(object):
    val = 2

@register
class C(object):
    var = 1
    val = 3
    name = 'cakes'
0 голосов
/ 01 октября 2018

Вы можете перебрать вывод функции locals() в конце файла и проверить _meta_dict_key.Если в объекте есть такой ключ, вы можете использовать его для создания базового dict.В питоне весь код, объявленный в файле верхнего уровня, выполняется только один раз при первом импорте, поэтому такой код можно безопасно разместить.

...