"abc" --- 抽象基底類別
**********************

**原始碼：**Lib/abc.py

======================================================================

如同在 **PEP 3119** 中所述，該模組提供了在 Python 中定義*抽象基底類別*
(ABC) 的基礎元件；若想瞭解為什麼需要在 Python 中增加這個模組，請見 PEP
文件。（也請見 **PEP 3141** 以及 "numbers" 模組以瞭解基於 ABC 的數字型
別階層關係。）

The "collections" module has some concrete classes that derive from
ABCs; these can, of course, be further derived. In addition, the
"collections.abc" submodule has some ABCs that can be used to test
whether a class or instance provides a particular interface, for
example, if it is *hashable* or if it is a *mapping*.

該模組提供了一個用來定義 ABC 的元類別 (metaclass) "ABCMeta" 和另一個以
繼承的方式定義 ABC 的工具類別 "ABC"：

class abc.ABC

   A helper class that has "ABCMeta" as its metaclass.  With this
   class, an abstract base class can be created by simply deriving
   from "ABC" avoiding sometimes confusing metaclass usage, for
   example:

      from abc import ABC

      class MyABC(ABC):
          pass

   Note that the type of "ABC" is still "ABCMeta", therefore
   inheriting from "ABC" requires the usual precautions regarding
   metaclass usage, as multiple inheritance may lead to metaclass
   conflicts. One may also define an abstract base class by passing
   the metaclass keyword and using "ABCMeta" directly, for example:

      from abc import ABCMeta

      class MyABC(metaclass=ABCMeta):
          pass

   在 3.4 版新加入.

class abc.ABCMeta

   用於定義抽象基底類別（ABC）的元類別。

   使用該元類別以建立一個 ABC。一個 ABC 可以像 mix-in 類別一樣直接被子
   類別繼承。你也可以將不相關的具體類別（甚至是內建類別）和 ABC 註冊為
   「虛擬子類別 (virtual subclass)」 —— 這些類別以及它們的子類別會被內
   建函式 "issubclass()" 識別為已註冊 ABC 的子類別，但是該 ABC 不會出
   現在其 MRO（Method Resolution Order，方法解析順序）中，由該 ABC 所
   定義的方法實作也不可呼叫（即使透過 "super()" 呼叫也不行）。[1]

   Classes created with a metaclass of "ABCMeta" have the following
   method:

   register(subclass)

      將*子類別*註冊為該 ABC 的「抽象子類別」，例如：

         from abc import ABC

         class MyABC(ABC):
             pass

         MyABC.register(tuple)

         assert issubclass(tuple, MyABC)
         assert isinstance((), MyABC)

      在 3.3 版的變更: 回傳已註冊的子類別，使其能夠作為類別裝飾器。

      在 3.4 版的變更: To detect calls to "register()", you can use
      the "get_cache_token()" function.

   你也可以覆寫 (override) 虛擬基底類別中的這個方法：

   __subclasshook__(subclass)

      （必須定義為類別方法。）

      Check whether *subclass* is considered a subclass of this ABC.
      This means that you can customize the behavior of "issubclass()"
      further without the need to call "register()" on every class you
      want to consider a subclass of the ABC.  (This class method is
      called from the "__subclasscheck__()" method of the ABC.)

      This method should return "True", "False" or "NotImplemented".
      If it returns "True", the *subclass* is considered a subclass of
      this ABC. If it returns "False", the *subclass* is not
      considered a subclass of this ABC, even if it would normally be
      one.  If it returns "NotImplemented", the subclass check is
      continued with the usual mechanism.

   為了對這些概念做一演示，請見以下定義 ABC 的範例：

      class Foo:
          def __getitem__(self, index):
              ...
          def __len__(self):
              ...
          def get_iterator(self):
              return iter(self)

      class MyIterable(ABC):

          @abstractmethod
          def __iter__(self):
              while False:
                  yield None

          def get_iterator(self):
              return self.__iter__()

          @classmethod
          def __subclasshook__(cls, C):
              if cls is MyIterable:
                  if any("__iter__" in B.__dict__ for B in C.__mro__):
                      return True
              return NotImplemented

      MyIterable.register(Foo)

   The ABC "MyIterable" defines the standard iterable method,
   "__iter__()", as an abstract method.  The implementation given here
   can still be called from subclasses.  The "get_iterator()" method
   is also part of the "MyIterable" abstract base class, but it does
   not have to be overridden in non-abstract derived classes.

   這裡定義的 "__subclasshook__()" 類別方法說明任何在其 "__dict__" (或
   在其透過 "__mro__" 列表訪問的基底類別) 中具有 "__iter__()" 方法的類
   別也都會被視為 "MyIterable"。

   Finally, the last line makes "Foo" a virtual subclass of
   "MyIterable", even though it does not define an "__iter__()" method
   (it uses the old-style iterable protocol, defined in terms of
   "__len__()" and "__getitem__()").  Note that this will not make
   "get_iterator" available as a method of "Foo", so it is provided
   separately.

The "abc" module also provides the following decorator:

@abc.abstractmethod

   用於表示抽象方法的裝飾器。

   Using this decorator requires that the class's metaclass is
   "ABCMeta" or is derived from it.  A class that has a metaclass
   derived from "ABCMeta" cannot be instantiated unless all of its
   abstract methods and properties are overridden.  The abstract
   methods can be called using any of the normal 'super' call
   mechanisms.  "abstractmethod()" may be used to declare abstract
   methods for properties and descriptors.

   Dynamically adding abstract methods to a class, or attempting to
   modify the abstraction status of a method or class once it is
   created, are only supported using the "update_abstractmethods()"
   function.  The "abstractmethod()" only affects subclasses derived
   using regular inheritance; "virtual subclasses" registered with the
   ABC's "register()" method are not affected.

   When "abstractmethod()" is applied in combination with other method
   descriptors, it should be applied as the innermost decorator, as
   shown in the following usage examples:

      class C(ABC):
          @abstractmethod
          def my_abstract_method(self, arg1):
              ...
          @classmethod
          @abstractmethod
          def my_abstract_classmethod(cls, arg2):
              ...
          @staticmethod
          @abstractmethod
          def my_abstract_staticmethod(arg3):
              ...

          @property
          @abstractmethod
          def my_abstract_property(self):
              ...
          @my_abstract_property.setter
          @abstractmethod
          def my_abstract_property(self, val):
              ...

          @abstractmethod
          def _get_x(self):
              ...
          @abstractmethod
          def _set_x(self, val):
              ...
          x = property(_get_x, _set_x)

   In order to correctly interoperate with the abstract base class
   machinery, the descriptor must identify itself as abstract using
   "__isabstractmethod__". In general, this attribute should be "True"
   if any of the methods used to compose the descriptor are abstract.
   For example, Python's built-in "property" does the equivalent of:

      class Descriptor:
          ...
          @property
          def __isabstractmethod__(self):
              return any(getattr(f, '__isabstractmethod__', False) for
                         f in (self._fget, self._fset, self._fdel))

   備註:

     不同於 Java 抽象方法，這些抽象方法可能具有一個實作。這個實作可在
     覆寫它的類別上透過 "super()" 機制來呼叫。這在使用協作多重繼承
     (cooperative multiple-inheritance) 的框架中，可以被用作 super 呼
     叫的一個端點 (end-point)。

The "abc" module also supports the following legacy decorators:

@abc.abstractclassmethod

   在 3.2 版新加入.

   在 3.3 版之後被棄用: 現在可以讓 "classmethod" 配合
   "abstractmethod()" 使用，使得此裝飾器變得冗餘。

   內建 "classmethod()" 的子類別，表示為一個抽象類別方法。在其他方面它
   都類似於 "abstractmethod()"。

   這個特例已被棄用，因為現在當 "classmethod()" 裝飾器應用於抽象方法時
   已會被正確地標識為是抽象的：

      class C(ABC):
          @classmethod
          @abstractmethod
          def my_abstract_classmethod(cls, arg):
              ...

@abc.abstractstaticmethod

   在 3.2 版新加入.

   在 3.3 版之後被棄用: 現在可以讓 "staticmethod" 配合
   "abstractmethod()" 使用，使得此裝飾器變得冗餘。

   內建 "staticmethod()" 的子類別，表示為一個抽象靜態方法。在其他方面
   它都類似於 "abstractmethod()"。

   這個特例已被棄用，因為現在當 "staticmethod()" 裝飾器應用於抽象方法
   時已會被正確地標識為是抽象的：

      class C(ABC):
          @staticmethod
          @abstractmethod
          def my_abstract_staticmethod(arg):
              ...

@abc.abstractproperty

   在 3.3 版之後被棄用: 現在可以讓 "property"、"property.getter()"、
   "property.setter()" 和 "property.deleter()" 配合 "abstractmethod()"
   使用，使得此裝飾器變得冗餘。

   內建 "property()" 的子類別，表示為一個抽象特性。

   這個特例已被棄用，因為現在當 "property()" 裝飾器應用於抽象方法時已
   會被正確地標識為是抽象的：

      class C(ABC):
          @property
          @abstractmethod
          def my_abstract_property(self):
              ...

   上面的例子定義了一個唯讀特性；你也可以透過適當地將一個或多個底層方
   法標記為抽象的來定義可讀寫的抽象特性：

      class C(ABC):
          @property
          def x(self):
              ...

          @x.setter
          @abstractmethod
          def x(self, val):
              ...

   如果只有某些元件是抽象的，則只需更新那些元件即可在子類別中建立具體
   的特性：

      class D(C):
          @C.x.setter
          def x(self, val):
              ...

The "abc" module also provides the following functions:

abc.get_cache_token()

   回傳當前 ABC 快取令牌 (cache token)。

   此令牌是一個（支援相等性測試的）不透明物件 (opaque object)，用於為
   虛擬子類別標識抽象基底類別快取的當前版本。此令牌會在任何 ABC 上每次
   呼叫 "ABCMeta.register()" 時發生更改。

   在 3.4 版新加入.

abc.update_abstractmethods(cls)

   重新計算一個抽象類別之抽象狀態的函式。如果一個類別的抽象方法在建立
   後被實作或被修改，則應當呼叫此函式。通常此函式應在一個類別裝飾器內
   部被呼叫。

   回傳 *cls*，使其能夠用作為類別的裝飾器。

   如果 *cls* 不是 "ABCMeta" 的實例則不做任何操作。

   備註:

     此函式會假定 *cls* 的超類別 (superclass) 已經被更新。它不會更新任
     何子類別。

   在 3.10 版新加入.

-[ 註解 ]-

[1] C++ 程式設計師需要注意到 Python 中虛擬基底類別的概念和 C++ 中的並
    不相同。
