Python 中的元類(metaclass)與抽象基類(ABCs)

元類:

元類的細緻解釋徹底能夠參考這篇博文:http://blog.jobbole.com/21351/html

這本是一篇 stack overflow 上的問答,被這位博主翻譯成了中文。講的很是細緻周全,這裏就再也不引用了,僅記錄幾個點:python

  • 總之,元類是一個比較高級而晦澀的概念,極少用到。因此即便不明白,或者明白了但不會用都沒大妨礙
  • 元類其實就是類的類,或者說,就像類被調用能夠產生實例同樣,元類用來產生類
  • 新式類的元類是 type,type 既是一個工廠函數又扮演着元類的角色,以下所示:
>>> type
<class 'type'>
>>> type(object)
<class 'type'>
>>> type(object) is type
True

這也就是在自定義元類的時候會看到 class MyMetaClass(type): 繼承自 type 的緣由linux

  • type(cls_name, cls_parents, cls_attr) 能夠這樣使用 type 來生成一個類
  • 元類的 __init__(),__new__() 方法比上面的 type 只多接受一個 cls 參數
  • 其實任意可調用對象均可以充當元類(賦值給 __metaclass__),不過使用類有額外的好處
  • __metaclass__ 屬性的搜索順序是這樣的:先尋找類屬性、而後是祖先類屬性,沒有就去模塊或全局裏找 __metaclass__ 變量。還找不到那這就是個傳統類,傳統類的元類是 types.ClassType

抽象基類:

一樣一個不經常使用的東西,因此也一樣的僅記錄一些知識點在這裏:函數

  • 抽象基類是用來繼承的,abc 模塊提供一個元類(ABCMeta)和兩個裝飾器(@abstractmethod 、 @abstractproperty)來自定義抽象基類
  • 使用了上面兩個裝飾器的基類不可實例化,而且被繼承的時候必須在子類裏覆蓋這些抽象方法(非抽象方法、屬性能夠不用覆蓋)
  • 抽象基類能夠經過繼承、或者ABCMeta的.register()方法來註冊:
>>> help(abc.ABCMeta.register)
Help on function register in module abc:

register(cls, subclass)
    Register a virtual subclass of an ABC.
    
    Returns the subclass, to allow usage as a class decorator.
  • 容器和迭代器類被ABCs化,數值類型也被ABCs化了。這些基類能夠在 collections 和 numbers 模塊裏找到

抽象基類的一些參考:

相關文章
相關標籤/搜索