2012-03-09 69 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

使用元類意味着您存儲在類本身中的所有信息。這也意味着信息是在創建類時存儲的,而不是隨後掃描所有信息。這意味着您需要擔心的是創建類 - 它們會被自動跟蹤。