abc — 추상 베이스 클래스

소스 코드: Lib/abc.py


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

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부터 폐지됨: 이제 classmethodabstractmethod() 를 함께 사용할 수 있어서, 이 데코레이터는 필요 없습니다.

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

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

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

버전 3.2에 추가.

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

내장 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에 추가.

각주