2014-02-13 23 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'>] 
>>>