abc --- abstract base class

Minamotoro: Lib/abc.py


This module provides components of the Abstract Base Class (ABC) defined in Python, in  This is outlined in PEP 3119 . Check out the PEP documentation to learn why you need to add this module to Python. (See also the PEP 3141 and numbers modules for ABC-based numbers Type inheritance relationship.)

There are some entity classes derived from ABC in the collections module; of course, these classes can 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 specific interface, for example, whether it is hashable or whether it is mapping etc.

This module provides a metaclass ABCMeta, which can be used to define abstract classes, and also provides a tool class < a i=3>ABC, which can be used to define abstract base classes through inheritance.

class abc.ABC

A auxiliary class using ABCMeta as a metaclass. Using this class, you can create an abstract base class by simply deriving from ABC , which will avoid the often confusing usage of metaclasses, such as:

from abc import ABC

class MyABC(ABC):
    pass

Please note that ABC is still of type ABCMeta, and therefore inherits ABC There are still considerations for using metaclasses, such as multiple inheritance that may lead to metaclass conflicts. You can also define an abstract base class by passing in the metaclass keyword and using ABCMeta directly, for example:

from abc import ABCMeta

class MyABC(metaclass=ABCMeta):
    pass

3.4 New features.

class abc.ABCMeta

Metaclass used to define abstract base classes (ABC).

Use this metaclass to create an abstract base class. Abstract base classes can be directly inherited by subclasses like mix-in classes. You can also register unrelated concrete classes (including built-in classes) and abstract base classes as "abstract subclasses" - these classes and their subclasses will be called by the built-in function issubclass () is recognized as a subclass of the corresponding abstract base class, but the abstract base class will not appear in its MRO (Method Resolution Order, method resolution order), which is implemented in the abstract base class Methods are also not callable (not even through super() ). 1

A class created using ABCMeta metaclass has the following methods:

register(subclass)

Register subclass as a "virtual subclass" of this ABC. For example:

from abc import ABC

class MyABC(ABC):
    pass

MyABC.register(tuple)

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

Changed in version 3.3: Returns the registered subclass, enabling it to be used as a class decorator.

Changed in version 3.4: To detect calls to register() you can use the get_cache_token() function .

You can also override this method in a virtual base class.

__subclasshook__(subclass)

(Must be defined as a class method.)

Check whether subclass is a subclass of ABC. This means you can further customize the behavior of issubclass() without having to call issubclass() on every class you wish to be a subclass of this ABC >register(). (This class method is called on the ABC's __subclasscheck__() method.)

This method must return TrueFalse or NotImplemented. If True is returned, subclass will be considered a subclass of this abstract base class. If False is returned, regardless of whether it should be considered a subclass under normal circumstances, it will be regarded as not. If NotImplemented is returned, the subclass check will continue according to the normal mechanism.

To demonstrate these concepts, consider the following example defining 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)

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

The __subclasshook__() class method defined here specifies any __dict__  (or in its base class accessed via a __mro__ list) has __iter__()< Classes with /span>MyIterable.  methods will also be treated as 

Finally, the last line makes Foo a virtual subclass of MyIterable even though it does not define __iter__( ) method (it uses __len__() and __getitem__()  The old-style iterable protocol defined by the term). Note that this will not make get_iterator a method available to Foo , so it will be provided separately.

abc The module also provides the following decorators:

@abc.abstractmethod

Decorator used to declare abstract methods.

Using this decorator requires that the metaclass of the class is ABCMeta or its derived class. A class with a metaclass derived from ABCMeta cannot be instantiated unless all of its abstract methods and trait properties have been overloaded. Abstract methods can be called via any ordinary 'super' calling mechanism. abstractmethod() Abstract methods that can be used to declare feature attributes and descriptors.

Dynamicly add abstract methods to a class, or attempt to modify the abstract state of a method or class after it is created. Only use update_abstractmethods() function is supported. abstractmethod() will only affect subclasses derived using regular inheritance; "virtual children" registered through ABC's register() method class" will not be affected.

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

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 mechanism, the descriptor must use __isabstractmethod__ to identify itself as abstract. Typically, if any of the methods that make up the descriptor are abstract, this attribute should be True. 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))

Remark

Unlike Java abstract methods, these abstract methods may have an implementation. This implementation can be called via the super() mechanism on classes that override it. This can be used as an endpoint for super calls in frameworks using cooperative multiple inheritance.

abc The module also supports the following legacy decorators:

@abc.abstractclassmethod

3.2 New features.

Removed since version 3.3: Now you can use classmethod with abstractmethod() is used, making this decorator redundant.

Built-in classmethod() subclass, indicating an abstract class method. Otherwise it is similar to abstractmethod().

This special case has been deprecated, as it is now correctly identified as when the classmethod() decorator is applied to an abstract method Abstract:

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

@abc.abstractstaticmethod

3.2 New features.

Removed since version 3.3: Now you can use staticmethod with abstractmethod() is used, making this decorator redundant.

Built-in staticmethod() subclass, indicating an abstract static method. Otherwise it is similar to abstractmethod().

This special case has been deprecated, as it is now correctly identified as when the staticmethod() decorator is applied to an abstract method Abstract:

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

@abc.abstractproperty

Removed since version 3.3: Now you can use propertyproperty.getter()< /span>property.deleter() to make this decorator redundant. abstractmethod() is used with  and property.setter()

A subclass of built-in property() that specifies an abstract property.

This special case has been deprecated, as it is now correctly identified as when the property() decorator is applied to an abstract method Abstract:

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

The above example defines a read-only trait property; you can also define read-write abstract trait properties by appropriately marking one or more underlying methods as abstract:

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

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

If only some components are abstract, just update those components to create concrete trait properties in the subclass:

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

abc The module also provides the following functions:

abc.get_cache_token()

Returns the cache token for the current abstract base class

This token is an opaque object (supports equality testing) that identifies the current version of the abstract base class cache for virtual subclasses. This token changes every time ABCMeta.register() is called on any ABC.

3.4 New features.

abc.update_abstractmethods(cls)

Function that recalculates the abstract state of an abstract class. This function should be called if a class's abstract method is implemented or modified after the class is created. Normally, this function should be called inside a class decorator.

returns cls, enabling it to be used as a class decorator.

If cls is not a subclass of ABCMeta , then No action is taken.

Remark

This function will assume that the superior class of cls has been updated. It won't update any subclasses.

New features in version 3.10.

Remark

1

C++ programmers need to note: the concept of virtual base classes in Python is not the same as in C++.

Guess you like

Origin blog.csdn.net/TalorSwfit20111208/article/details/135028849