动态检索关于在 module/script 中声明的 python 类 的元信息

Dynamically retrieve meta information about python classes declared in module/script

我有一组类,我希望能够从字典动态初始化。

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 dict 保持最新。有没有办法根据脚本中声明的类动态构造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} 

您可以在文件末尾遍历 locals() 函数的输出并检查 _meta_dict_key。如果对象中有这样的key,就可以用它来构造base dict。 在 python 中,在文件顶层声明的所有代码在第一次导入时只执行一次,因此将此类代码放在那里是安全的。

Python 有 class 个装饰器,所以一个干净的方法可能是这样的:

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'