2012-03-09 6 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の "プロジャンゴ" の本を読み始めました。そこでは、彼はサブクラスを追跡するメタクラスの利用を提案している:

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

+0

@yakありがとうございます。だから '_tab'は良いでしょうか?または '_tab_'ですか? (私はおそらくそれをとにかくデコレータに置き換えます。) –

答えて

2

メタクラスを使用するということは、クラス内部に保存したすべての情報を意味します。また、後ですべてをスキャンするのではなく、クラスが作成されるときに情報が格納されることを意味します。これは、あなたが心配する必要があるのは、クラスを作成することです。クラスは自動的に追跡されます。

関連する問題