2012-03-09 35 views
1

对于Django选项卡库,我创建了一个使用跟踪标记的子类的体系结构。Python子类跟踪 - 元类与内建

为此,我创建了一个基类,然后从中派生出所有的选项卡类。我使用递归使用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 

现在我开始阅读马蒂Alchin的 “临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__()更好吗?

+0

不要发明'__foo__'名字。 – yak 2012-03-09 09:23:48

+0

@yak感谢您的评论。所以'_tab'会更好?或'_tab_'? (无论如何,我可能会用装饰器替换它。) – 2012-03-09 10:23:42

回答

2

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