# `abc` — 추상 베이스 클래스

소스 코드: 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

  버전 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.

  여기에 정의된 `__subclasshook__()` 클래스 메서드는 자신의 (또는 그것의 `__mro__` 리스트를 통해 액세스 되는 베이스 클래스 중 하나의) `__dict__` 에 `__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))

  참고

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

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

@abc.abstractclassmethod

  버전 3.2에 추가.

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

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

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

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

@abc.abstractstaticmethod

  버전 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()` 가 호출될 때마다 토큰이 변경됩니다.

  버전 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.

  버전 3.10에 추가.

각주

[1]

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