Для библиотеки вкладок Django я создал архитектуру, которая использует отслеживание отмеченных подклассов.
Для этого я создал базовый класс и затем извлек из него все классы вкладок.Я отслеживаю классы-потомки, используя функцию, которая рекурсивно использует метод * 1003. *любой класс, который я хочу показать в виде вкладки.Причина этого в том, что я создаю другие классы абстракции ниже 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
Теперь я начал читать книгу Марти Алчина «Pro 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__()
?