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 子类跟踪 - 元类与内置的主要内容,如果未能解决你的问题,请参考以下文章