在Python中扩展类时执行代码

时间:2014-02-13 14:05:44

标签: python class subclass introspection

当一个类被另一个类扩展时,有没有办法在Python中执行一些代码?更准确地说,我想自动保留扩展基类的所有类的寄存器。因此,我想写一些类似的东西:

class Base:

    subclasses = {}

    @classmethod
    def extending(cls, subclass):
        cls.subclasses[subclass.__name__] = subclass

class Extend1(Base):
    pass

class Extend2(Base):
    pass

在这段代码之后,我希望Base.subclasses包含指向两个扩展类的链接。

你能建议一种让这项工作的方法吗?或者,也许,提供一个等效的解决方案?

2 个答案:

答案 0 :(得分:3)

这显然是元类的应用程序。也就是说,如果你想改变classe C的行为,你应该改变C本身的类,这是一个元类,通常是type。这是一个解决方案的存根:

class Meta(type):
    def __new__(cls, clsname, bases, dct):
        res = type.__new__(cls, clsname, bases, dct)
        for cls in bases:
            if isinstance(cls, Meta):
                try:
                    cls.extending(res)
                except AttributeError:
                    pass
        return res

我继承自type,使得元类拦截类的创建并将创建的类存储在基类_subclass属性中。然后用

class Base(object):
    __metaclass__ = Meta

    subclasses = {}

    @classmethod
    def extending(cls, subclass):
        cls.subclasses[subclass.__name__] = subclass

class Extend1(Base):
    pass

class Extend2(Base):
    pass

然后

>>> Base.subclasses
{'Extend1': __main__.Extend1, 'Extend2': __main__.Extend2}

非常重要的一点:元类是inherited(我认为这不是正确的术语)。因此,Extend1Extend2也是Meta的实例:

>>> type(Extend1)
<class '__main__.Meta'>

答案 1 :(得分:2)

实际上,如果你只对子类感兴趣,python可以自动给你。所有新样式类都有一个__subclasses__()方法,它返回所有类的直接后代。

>>> class Base(object):
...     pass
...
>>> class Child(Base):
...     pass
...
>>> Base.__subclasses__()
[<class '__main__.Child'>]
>>>