2012-03-09 3 views
1

Для библиотеки вкладок Django я создал архитектуру, которая использует отслеживание отмеченных подклассов.Отслеживание подкласса Python - метаклассы vs Builtin

Для этого я создал базовый класс, а затем вывел из него все классы вкладок. Я отслеживаю классы потомков, используя функцию, которая рекурсивно использует метод 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 в. Там, он предлагает использование метаклассов для отслеживания подклассов:

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

Использование метаклассов означает, что вся информация, которую вы сохранили внутри самого класса. Это также означает, что информация хранится по мере создания классов, а не сканирования всех из них впоследствии. Это означает, что все, о чем вам нужно беспокоиться, это создавать классы - они отслеживаются автоматически.