动态检索有关在模块/脚本中声明的python类的元信息

时间:2018-10-01 12:09:14

标签: python class oop metaprogramming

我有一组可以通过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 :(得分:2)

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'

答案 1 :(得分:0)

您可以遍历文件末尾的locals()函数的输出,并检查_meta_dict_key。如果对象中有这样的键,则可以使用它来构造基本字典。 在python中,在文件顶级声明的所有代码在第一次导入时仅执行一次,因此可以安全地将此类代码放在其中。