Python 子类跟踪 - 元类与内置

Posted

技术标签:

【中文标题】Python 子类跟踪 - 元类与内置【英文标题】:Python Subclass Tracking - Metaclasses vs Builtin 【发布时间】:2012-03-26 17:26:03 【问题描述】:

对于 Django 选项卡库,我创建了一个使用标记子类跟踪的架构。

为此,我创建了一个基类,然后从中派生所有选项卡类。我使用递归使用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 的“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__()好吗?

【问题讨论】:

永远不要发明__foo__的名字。 @yak 感谢您的评论。所以_tab 会更好吗?或_tab_? (无论如何,我可能会用装饰器替换它。) 【参考方案1】:

使用元类意味着您存储在类本身内部的所有信息。这也意味着信息是在创建类时存储的,而不是之后扫描所有类。这意味着您只需要担心创建类 - 它们会被自动跟踪。

【讨论】:

以上是关于Python 子类跟踪 - 元类与内置的主要内容,如果未能解决你的问题,请参考以下文章

exec模块,元类与ORV的应用

Python 元类与类装饰器

python:元类与抽象基类

markdown Python Metaclass元类与对象的关系,抽象类

16 元类

反射,元类