通用元类来跟踪子类?
我正在尝试编写一个通用元类来跟踪子类,
因为我希望这是通用的,所以我不想在这个元类中硬编码任何类名,因此我想出了一个生成正确元类的函数,例如:
def make_subtracker(root):
class SubclassTracker(type):
def __init__(cls, name, bases, dct):
print('registering %s' % (name,))
root._registry.append(cls)
super(SubclassTracker, cls).__init__(name, bases, dct)
return SubclassTracker
这样我就可以调用它来为特定的root类生成元类:
__metaclass__ = make_subtracker(Root)
这是我遇到问题的地方。我不能这样做:
class Root(object):
_registry = []
__metaclass__ = make_subtracker(Root)
...因为当我使用 make_subtracker(Root)
时,Root
尚未定义。我稍后尝试添加 __metaclass__ 属性,这样至少它可以应用于子类中:
class Root(object):
_registry = []
Root.__metaclass__ = make_subtracker(Root)
...但这不起作用。 __metaclass__ 在读取类定义时有一个特殊的处理,如 自定义类创建。
我正在寻找建议来做到这一点(在运行时更改类的元类,将其应用于其子类,或者任何其他替代方案)。
I'm trying to write a generic metaclass to track subclasses
Since I want this to be generic, I didn't want to hardcode any class name within this metaclass, therefore I came up with a function that generates the proper metaclass, something like:
def make_subtracker(root):
class SubclassTracker(type):
def __init__(cls, name, bases, dct):
print('registering %s' % (name,))
root._registry.append(cls)
super(SubclassTracker, cls).__init__(name, bases, dct)
return SubclassTracker
This way I could invoke it to generate a metaclass for a specific root class with:
__metaclass__ = make_subtracker(Root)
Here is where I bump into a problem. I cannot do this:
class Root(object):
_registry = []
__metaclass__ = make_subtracker(Root)
...because Root
is not defined yet when I use make_subtracker(Root)
. I tried adding the __metaclass__ attribute later, so that at least it can be applied in subclasses:
class Root(object):
_registry = []
Root.__metaclass__ = make_subtracker(Root)
...but this doesn't work. __metaclass__ has a special processing when the class definition is read, as defined in Customizing class creation.
I'm looking for suggestions in order to do this (either change a class' metaclass at runtime in a way that it is applied to its subclasses, or any other alternative).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
Python 会自动为新型类执行此操作,如 回答类似的问题如何查找给定名称的类的所有子类? 此处。
Python does this automatically for new-style classes, as mentioned in this answer to the similar queston How to find all the subclasses of a class given its name? here.
我认为你想要这样的东西(未经测试):
然后,对于 Python 2,你可以像这样调用它:
对于 Python 3
请注意,你不需要将
_registry
属性粘贴在那里,因为像这样的东西这就是元类的用途。因为您已经碰巧拥有一个...;)另请注意,您可能希望将注册代码移至
else
子句中,以便该类不会将自身注册为子类。I think you want something like this (untested):
Then, for Python 2, you can invoke it like:
for Python 3
Note that you don't need to stick the
_registry
attribute on there because stuff like that is what metaclasses are for. Since you already happen to have one laying around... ;)Note also that you might want to move the registration code into an
else
clause so that the class doesn't register itself as a subclass.这是我一直在尝试的东西(有效):
Here's something I've been playing around with (that works):