日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
創(chuàng)新互聯(lián)Python教程:abc—-抽象基類

abc —- 抽象基類

源代碼: Lib/abc.py


該模塊提供了在 python 中定義 抽象基類 (ABC) 的組件,在 PEP 3119 中已有概述。查看 PEP 文檔了解為什么需要在 Python 中增加這個模塊。(也可查看 PEP 3141 以及 numbers 模塊了解基于 ABC 的數(shù)字類型繼承關(guān)系。)

collections 模塊中有一些派生自 ABC 的具體類;當然這些類還可以進一步被派生。此外,collections.abc 子模塊中有一些 ABC 可被用于測試一個類或?qū)嵗欠裉峁┨囟ǖ慕涌?,例如它是否可哈?;蛩欠駷橛成涞取?/p>

該模塊提供了一個元類 ABCMeta,可以用來定義抽象類,另外還提供一個工具類 ABC,可以用它以繼承的方式定義抽象基類。

class abc.ABC

一個使用 ABCMeta 作為元類的工具類。抽象基類可以通過從 ABC 派生來簡單地創(chuàng)建,這就避免了在某些情況下會令人混淆的元類用法,例如:

 
 
 
 
  1. from abc import ABC
  2. class MyABC(ABC):
  3. pass

注意 ABC 的類型仍然是 ABCMeta,因此繼承 ABC 仍然需要關(guān)注元類使用中的注意事項,比如可能會導(dǎo)致元類沖突的多重繼承。當然你也可以直接使用 ABCMeta 作為元類來定義抽象基類,例如:

 
 
 
 
  1. from abc import ABCMeta
  2. class MyABC(metaclass=ABCMeta):
  3. pass

3.4 新版功能.

class abc.ABCMeta

用于定義抽象基類(ABC)的元類。

使用該元類以創(chuàng)建抽象基類。抽象基類可以像 mix-in 類一樣直接被子類繼承。你也可以將不相關(guān)的具體類(包括內(nèi)建類)和抽象基類注冊為“抽象子類” —— 這些類以及它們的子類會被內(nèi)建函數(shù) issubclass() 識別為對應(yīng)的抽象基類的子類,但是該抽象基類不會出現(xiàn)在其 MRO(Method Resolution Order,方法解析順序)中,抽象基類中實現(xiàn)的方法也不可調(diào)用(即使通過 super() 調(diào)用也不行)。1

使用 ABCMeta 作為元類創(chuàng)建的類含有如下方法:

  • register(subclass)

    將“子類”注冊為該抽象基類的“抽象子類”,例如:

       
       
       
       
    1. from abc import ABC
    2. class MyABC(ABC):
    3. pass
    4. MyABC.register(tuple)
    5. assert issubclass(tuple, MyABC)
    6. assert isinstance((), MyABC)

    在 3.3 版更改: 返回注冊的子類,使其能夠作為類裝飾器。

    在 3.4 版更改: 你可以使用 get_cache_token() 函數(shù)來檢測對 register() 的調(diào)用。

你也可以在虛基類中重載這個方法。

  • __subclasshook__(subclass)

    (必須定義為類方法。)

    檢查 subclass 是否是該抽象基類的子類。也就是說對于那些你希望定義為該抽象基類的子類的類,你不用對每個類都調(diào)用 register() 方法了,而是可以直接自定義 issubclass 的行為。(這個類方法是在抽象基類的 __subclasscheck__() 方法中調(diào)用的。)

    該方法必須返回 True, False 或是 NotImplemented。如果返回 Truesubclass 就會被認為是這個抽象基類的子類。如果返回 False,無論正常情況是否應(yīng)該認為是其子類,統(tǒng)一視為不是。如果返回 NotImplemented,子類檢查會按照正常機制繼續(xù)執(zhí)行。

為了對這些概念做一演示,請看以下定義 ABC 的示例:

 
 
 
 
  1. class Foo:
  2. def __getitem__(self, index):
  3. ...
  4. def __len__(self):
  5. ...
  6. def get_iterator(self):
  7. return iter(self)
  8. class MyIterable(ABC):
  9. @abstractmethod
  10. def __iter__(self):
  11. while False:
  12. yield None
  13. def get_iterator(self):
  14. return self.__iter__()
  15. @classmethod
  16. def __subclasshook__(cls, C):
  17. if cls is MyIterable:
  18. if any("__iter__" in B.__dict__ for B in C.__mro__):
  19. return True
  20. return NotImplemented
  21. MyIterable.register(Foo)

ABC MyIterable 定義了標準的迭代方法 __iter__() 作為一個抽象方法。這里給出的實現(xiàn)仍可在子類中被調(diào)用。get_iterator() 方法也是 MyIterable 抽象基類的一部分,但它并非必須被非抽象派生類所重載。

這里定義的 __subclasshook__() 類方法指明了任何在其 __dict__ (或在其通過 __mro__ 列表訪問的基類) 中具有 __iter__() 方法的類也都會被視為 MyIterable。

最后,末尾行使得 Foo 成為 MyIterable 的一個虛子類,即使它沒有定義 __iter__() 方法(它使用了以 __len__()__getitem__() 術(shù)語定義的舊式可迭代對象協(xié)議)。 請注意這將不會使 get_iterator 成為 Foo 的一個可用方法,它是被另外提供的。

此外,abc 模塊還提供了這些裝飾器:

@abc.abstractmethod

用于聲明抽象方法的裝飾器。

使用此裝飾器要求類的元類是 ABCMeta 或是從該類派生。一個具有派生自 ABCMeta 的元類的類不可以被實例化,除非它全部的抽象方法和特征屬性均已被重載。抽象方法可通過任何普通的“super”調(diào)用機制來調(diào)用。 abstractmethod() 可被用于聲明特性屬性和描述器的抽象方法。

動態(tài)地添加抽象方法到一個類,或嘗試在方法或類被創(chuàng)建后修改其抽象狀態(tài)等操作僅在使用 update_abstractmethods() 函數(shù)時受到支持。 abstractmethod() 只會影響使用常規(guī)繼承所派生的子類;通過 ABC 的 register() 方法注冊的“虛子類”不會受到影響。

當 abstractmethod() 與其他方法描述符配合應(yīng)用時,它應(yīng)當被應(yīng)用為最內(nèi)層的裝飾器,如以下用法示例所示:

 
 
 
 
  1. class C(ABC):
  2. @abstractmethod
  3. def my_abstract_method(self, arg1):
  4. ...
  5. @classmethod
  6. @abstractmethod
  7. def my_abstract_classmethod(cls, arg2):
  8. ...
  9. @staticmethod
  10. @abstractmethod
  11. def my_abstract_staticmethod(arg3):
  12. ...
  13. @property
  14. @abstractmethod
  15. def my_abstract_property(self):
  16. ...
  17. @my_abstract_property.setter
  18. @abstractmethod
  19. def my_abstract_property(self, val):
  20. ...
  21. @abstractmethod
  22. def _get_x(self):
  23. ...
  24. @abstractmethod
  25. def _set_x(self, val):
  26. ...
  27. x = property(_get_x, _set_x)

為了能正確地與抽象基類機制實現(xiàn)互操作,描述符必須使用 __isabstractmethod__ 將自身標識為抽象的。 通常,如果被用于組成描述符的任何方法都是抽象的則此屬性應(yīng)當為 True。 例如,Python 的內(nèi)置 property 所做的就等價于:

 
 
 
 
  1. class Descriptor:
  2. ...
  3. @property
  4. def __isabstractmethod__(self):
  5. return any(getattr(f, '__isabstractmethod__', False) for
  6. f in (self._fget, self._fset, self._fdel))

備注

不同于 Java 抽象方法,這些抽象方法可能具有一個實現(xiàn)。 這個實現(xiàn)可在重載它的類上通過 super() 機制來調(diào)用。 這在使用協(xié)作多重繼承的框架中可以被用作超調(diào)用的一個端點。

abc 模塊還支持下列舊式裝飾器:

@abc.abstractclassmethod

3.2 新版功能.

3.3 版后已移除: 現(xiàn)在可以讓 classmethod 配合 abstractmethod() 使用,使得此裝飾器變得冗余。

內(nèi)置 classmethod() 的子類,指明一個抽象類方法。 在其他方面它都類似于 abstractmethod()。

這個特例已被棄用,因為現(xiàn)在當 classmethod() 裝飾器應(yīng)用于抽象方法時它會被正確地標識為抽象的:

 
 
 
 
  1. class C(ABC):
  2. @classmethod
  3. @abstractmethod
  4. def my_abstract_classmethod(cls, arg):
  5. ...

@abc.abstractstaticmethod

3.2 新版功能.

3.3 版后已移除: 現(xiàn)在可以讓 staticmethod 配合 abstractmethod() 使用,使得此裝飾器變得冗余。

內(nèi)置 staticmethod() 的子類,指明一個抽象靜態(tài)方法。 在其他方面它都類似于 abstractmethod()。

這個特例已被棄用,因為現(xiàn)在當 staticmethod() 裝飾器應(yīng)用于抽象方法時它會被正確地標識為抽象的:

 
 
 
 
  1. class C(ABC):
  2. @staticmethod
  3. @abstractmethod
  4. def my_abstract_staticmethod(arg):
  5. ...

@abc.abstractproperty

3.3 版后已移除: 現(xiàn)在可以讓 property, property.getter(), property.setter()property.deleter() 配合 abstractmethod() 使用,使得此裝飾器變得冗余。

內(nèi)置 property() 的子類,指明一個抽象特性屬性。

這個特例已被棄用,因為現(xiàn)在當 property() 裝飾器應(yīng)用于抽象方法時它會被正確地標識為抽象的:

 
 
 
 
  1. class C(ABC):
  2. @property
  3. @abstractmethod
  4. def my_abstract_property(self):
  5. ...

上面的例子定義了一個只讀特征屬性;你也可以通過適當?shù)貙⒁粋€或多個下層方法標記為抽象的來定義可讀寫的抽象特征屬性:

 
 
 
 
  1. class C(ABC):
  2. @property
  3. def x(self):
  4. ...
  5. @x.setter
  6. @abstractmethod
  7. def x(self, val):
  8. ...

如果只有某些組件是抽象的,則只需更新那些組件即可在子類中創(chuàng)建具體的特征屬性:

 
 
 
 
  1. class D(C):
  2. @C.x.setter
  3. def x(self, val):
  4. ...

abc 模塊還提供了這些函數(shù):

abc.get_cache_token()

返回當前抽象基類的緩存令牌

此令牌是一個不透明對象(支持相等性測試),用于為虛子類標識抽象基類緩存的當前版本。 此令牌會在任何 ABC 上每次調(diào)用 ABCMeta.register() 時發(fā)生更改。

3.4 新版功能.

abc.update_abstractmethods(cls)

重新計算一個抽象類的抽象狀態(tài)的函數(shù)。 如果一個類的抽象方法在類被創(chuàng)建后被實現(xiàn)或被修改則應(yīng)當調(diào)用此函數(shù)。 通常,此函數(shù)應(yīng)當在一個類裝飾器內(nèi)部被調(diào)用。

返回 cls,使其能夠用作類裝飾器。

如果 cls 不是 ABCMeta 的子類,則不做任何操作。

備注

此函數(shù)會假定 cls 的上級類已經(jīng)被更新。 它不會更新任何子類。

3.10 新版功能.

備注

1

C++ 程序員需要注意:Python 中虛基類的概念和 C++ 中的并不相同。


文章題目:創(chuàng)新互聯(lián)Python教程:abc—-抽象基類
URL地址:http://www.dlmjj.cn/article/djecidi.html