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__()
を使用するよりも優れていますか?
'__foo__'名は決して作らないでください。コメントのために – yak
@yakありがとうございます。だから '_tab'は良いでしょうか?または '_tab_'ですか? (私はおそらくそれをとにかくデコレータに置き換えます。) –