我有一个类层次结构,我想注册它,以便以后可以访问它。到目前为止,我一直在手动完成:
class FirstClass(MyBaseClass):
....
registry.register(FirstClass)
class SecondClass(FirstClass):
....
registry.register(SecondClass)
我正在寻找一种在评估类时(即,当有人导入带有该类的包时)调用 registry.register(Class)
的方法,而不必显式调用它.
我想我必须向 MyBaseClass
添加一些东西,但我不知道是什么。所有特殊方法似乎都与实例相关,而不是与类相关。
有办法做到这一点吗?
说明: 注册表跟踪从 BaseClass 派生的类。在代码中的某个时刻,我会检查所有这些类并实例化对象。它比这更复杂一些,因为注册表还做其他事情,但这就是主要思想。
最佳答案
这正是元类的用途:将操作应用于整个类层次结构:
In [1]: def register(cls):
...: # just to show when it is called.
...: print('Register: {}'.format(cls))
...:
...:
...: class MyMeta(type):
...: def __new__(cls, name, bases, attrs):
...: the_cls = super().__new__(cls, name, bases, attrs)
...: register(the_cls)
...: return the_cls
In [2]: class FirstClass(metaclass=MyMeta):
...: pass
...:
Register: <class '__main__.FirstClass'>
In [3]: class SecondClass(FirstClass):
...: pass
...:
Register: <class '__main__.SecondClass'>
请注意,您必须仅在层次结构的根中添加元类,并且它将在所有子类中继承,因此您只需将其添加为 MyBaseClass
你就完成了。
有关深入的解释,请参阅这个问题:What is a metaclass in Python?
我使用了python3语法。在 python2 中要添加元类,您必须设置 __metaclass__
属性:
class MyClass(object):
__metaclass__ = MyMeta
我想指出,要获取类的子类,您可以使用 __subclasses__
方法。不需要显式地跟踪它们,也不需要使用自定义元类:
In [4]: FirstClass.__subclasses__()
Out[4]: [__main__.SecondClass]
关于python - 当计算 Python 类时如何运行代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24229162/