2014-02-13 20 views
1

当一个类被另一个类扩展时,是否有一种方法可以在Python中执行某些代码?更确切地说,我想自动保存所有扩展基类的类的注册表。因此,我想写这样的东西:在Python中扩展类时执行代码

class Base: 

    subclasses = {} 

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

class Extend1(Base): 
    pass 

class Extend2(Base): 
    pass 

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

你能提出一种方法来完成这项工作吗?或者,也许,提供一个同等的解决方案?

回答

3

这显然是元类的应用。这就是说,如果你想改变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'> 
2

实际上,如果你只在子类兴趣,Python可以自动给你。所有新的风格类都有一个__subclasses__()方法,该方法返回所有类的直接后代。

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