"abc" --- Abstract Base Classes
*******************************

**소스 코드:** Lib/abc.py

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

이 모듈은, **PEP 3119**에서 설명된 대로, 파이썬에서 *추상 베이스 클래
스* (ABC) 를 정의하기 위한 기반 구조를 제공합니다; 이것이 왜 파이썬에
추가되었는지는 PEP를 참조하십시오. (ABC를 기반으로 하는 숫자의 형 계층
구조에 관해서는 **PEP 3141**과 "numbers" 모듈을 참고하십시오.)

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를 정의하기 위한 메타 클래스 "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

   Added in version 3.4.

class abc.ABCMeta

   추상 베이스 클래스 (ABC)를 정의하기 위한 메타 클래스.

   이 메타 클래스를 사용하여 ABC를 만듭니다. ABC는 직접 서브 클래싱 될
   수 있으며 믹스인 클래스의 역할을 합니다. 관련 없는 구상 클래스(심지
   어 내장 클래스도)와 관련 없는 ABC를 "가상 서브 클래스"로 등록 할 수
   있습니다 -- 이들과 이들의 서브 클래스는 내장 "issubclass()" 함수에
   의해 등록하는 ABC의 서브 클래스로 간주합니다. 하지만 등록하는 ABC는
   그들의 MRO (메서드 결정 순서)에 나타나지 않을 것이고, 등록하는 ABC
   가 정의한 메서드 구현도 호출할 수 없을 것입니다 ("super()"를 통해서
   도 가능하지 않습니다). [1]

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

   register(subclass)

      이 ABC의 "가상 서브 클래스"로 *subclass* 를 등록합니다. 예를 들
      면:

         from abc import ABC

         class MyABC(ABC):
             pass

         MyABC.register(tuple)

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

      버전 3.3에서 변경: 클래스 데코레이터로 사용할 수 있도록, 등록된
      subclass 돌려줍니다.

      버전 3.4에서 변경: To detect calls to "register()", you can use
      the "get_cache_token()" function.

   추상 베이스 클래스에서 다음 메서드를 재정의할 수도 있습니다:

   __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.

   The "__subclasshook__()" class method defined here says that any
   class that has an "__iter__()" method in its "__dict__" (or in that
   of one of its base classes, accessed via the "__mro__" list) is
   considered a "MyIterable" too.

   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))

   참고:

     자바 추상 메서드와 달리, 이 추상 메서드는 구현을 가질 수 있습니다
     . 이 구현은 그것을 재정의하는 클래스에서 "super()" 메커니즘을 통
     해 호출 할 수 있습니다. 이는 협업적 다중 상속을 사용하는 프레임워
     크에서 super-호출의 종점으로 유용 할 수 있습니다.

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

@abc.abstractclassmethod

   Added in version 3.2.

   버전 3.3부터 폐지됨: 이제 "classmethod" 와 "abstractmethod()" 를 함
   께 사용할 수 있어서, 이 데코레이터는 필요 없습니다.

   내장 "classmethod()" 의 서브 클래스로, 추상 classmethod를 나타냅니
   다. 그 외에는 "abstractmethod()" 와 유사합니다.

   "classmethod()" 데코레이터가 이제 추상 메서드에 적용될 때 추상으로
   정확하게 식별되기 때문에, 이 특별한 경우는 폐지되었습니다.:

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

@abc.abstractstaticmethod

   Added in version 3.2.

   버전 3.3부터 폐지됨: 이제 "staticmethod" 와 "abstractmethod()" 를
   함께 사용할 수 있어서, 이 데코레이터는 필요 없습니다.

   내장 "staticmethod()" 의 서브 클래스로, 추상 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를 나타냅니다.

   "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
   에서 "ABCMeta.register()" 가 호출될 때마다 토큰이 변경됩니다.

   Added in version 3.4.

abc.update_abstractmethods(cls)

   A function to recalculate an abstract class's abstraction status.
   This function should be called if a class's abstract methods have
   been implemented or changed after it was created. Usually, this
   function should be called from within a class decorator.

   Returns *cls*, to allow usage as a class decorator.

   If *cls* is not an instance of "ABCMeta", does nothing.

   참고:

     This function assumes that *cls*'s superclasses are already
     updated. It does not update any subclasses.

   Added in version 3.10.

-[ 각주 ]-

[1] C++ 프로그래머는 파이썬의 가상 베이스 클래스 개념이 C++과 다르다는
    것을 알아야 합니다.
