Python子类跟踪 - 元类与内置

时间:2012-03-09 08:36:16

标签: python django metaclass subclass

对于Django选项卡库,我创建了一个使用跟踪标记子类的架构。

为此,我创建了一个基类,然后从中派生所有选项卡类。我使用递归使用cls.__subclasses__()方法的函数跟踪后代类。

为了知道哪些子类是叶子类/真实选项卡,我选择以手动方式执行此操作,方法是将__tab__ = True添加到我想要显示为选项卡的任何类中。这样做的原因是我正在创建TabView以下的其他抽象类,这些抽象类不应该显示为选项卡。也许这可以作为装饰师重写。

示例:

def get_descendants(cls):
    """Returns all subclasses for cls, and their sublasses, and so on..."""
    descendants = []
    subclasses = cls.__subclasses__()
    for subclass in subclasses:
        descendants.append(subclass)
        descendants += get_descendants(subclass)
    return descendants

def TabView(object):
    def _tab_group_members(self):
        descendants = get_descendants(TabView)
        return [d for d in descendants if '__tab__' in d.__dict__]
    (...)

def ConcreteTab(TabView):
    __tab__ = True

现在我开始阅读Marty Alchin的“Pro Django”一书。在那里,他建议使用元类来跟踪子类:

class SubclassTracker(type):
    def __init__(cls, name, bases, attrs):
        try:
            if TrackedClass not in bases:
                return
        except NameError:
            return
        TrackedClass._registry.append(cls)

class TrackedClass(object):
    __metaclass__ = SubclassTracker
    _registry = []

元类方法有哪些优点?它比使用__subclasses__()更好吗?

1 个答案:

答案 0 :(得分:2)

使用元类意味着您存储在类本身内的所有信息。它还意味着信息在创建类时存储,而不是在之后扫描所有类。这意味着您需要担心的是创建类 - 它们会被自动跟踪。