abc
— 抽象基类
¶
2.6 版新增。
源代码: Lib/abc.py
本模块提供基础设施为定义
抽象基类
(ABC) 在 Python 中,如提纲于
PEP 3119
;见 PEP 了解为什么要把这添加到 Python (另请参阅
PEP 3141
和
numbers
模块关于基于 ABC 的数字类型层次结构)。
The
collections
模块有一些派生自 ABC (抽象基类) 的具体类;当然,这些可以进一步派生。此外,
collections
module 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.
This module provides the following class:
abc.
ABCMeta
¶
用于定义 ABC (抽象基类) 的元类。
使用此元类能创建 ABC (抽象基类)。可以直接子类化 ABC,然后充当混合类。还可以把不相关具体类 (甚至是内置类) 和不相关 ABC 注册成 "虚拟子类" – 将把这些类及它们的后代认为是注册 ABC 的子类通过内置
issubclass()
函数,但注册的 ABC 既不会出现在它们的 MRO (方法分辨次序) 中,由注册的 ABC 定义的方法实现也不可调用 (甚至无法透过
super()
).
1
类创建采用元类化的
ABCMeta
拥有以下方法:
register
(
子类
)
¶
注册 subclass 作为此 ABC 的 "虚拟子类"。例如:
from abc import ABCMeta class MyABC: __metaclass__ = ABCMeta MyABC.register(tuple) assert issubclass(tuple, MyABC) assert isinstance((), MyABC)
也可以覆盖抽象基类中的此方法:
__subclasshook__
(
子类
)
¶
(必须定义成类方法)。
校验是否
subclass
被认为是此 ABC 的子类。这意味着可以定制行为若
issubclass
进一步不需要调用
register()
对于想要考虑子类化 ABC 的各类 (调用此类方法是从
__subclasscheck__()
方法对于 ABC)。
此方法应返回
True
,
False
or
NotImplemented
。若它返回
True
,
subclass
被认为是此 ABC 的子类。若它返回
False
,
subclass
不被认为是此 ABC 的子类,即使它通常是。若它返回
NotImplemented
,采用通常机制继续校验子类。
为演示这些概念,查看这些范例 ABC 定义:
class Foo(object): def __getitem__(self, index): ... def __len__(self): ... def get_iterator(self): return iter(self) class MyIterable: __metaclass__ = ABCMeta @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
定义标准可迭代方法
__iter__()
,作为抽象方法。这里给出的实现仍然可以从子类调用。
get_iterator()
方法还属于
MyIterable
抽象基类,但不必在非抽象派生类覆写它。
The
__subclasshook__()
类方法定义在这里说任何类拥有
__iter__()
方法在其
__dict__
(或在其基类,访问凭借
__mro__
列表) 被认为是
MyIterable
也。
最终,最后行制作
Foo
虚拟子类化的
MyIterable
,即使它没有定义
__iter__()
方法 (使用旧式可迭代协议,其定义在术语
__len__()
and
__getitem__()
)。注意,这不会使
get_iterator
可用作方法对于
Foo
,所以它是单独提供的。
It also provides the following decorators:
abc.
abstractmethod
(
function
)
¶
指示抽象方法的装饰器。
使用此装饰器要求类的元类是
ABCMeta
或是来自它的派生。拥有元类的类派生自
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.
Dynamically adding abstract methods to a class, or attempting to modify the abstraction status of a method or class once it is created, are not supported. The
abstractmethod()
only affects subclasses derived using regular inheritance; “virtual subclasses” registered with the ABC’s
register()
method are not affected.
用法:
class C: __metaclass__ = ABCMeta @abstractmethod def my_abstract_method(self, ...): ...
注意
Unlike Java abstract methods, these abstract methods may have an implementation. This implementation can be called via the
super()
mechanism from the class that overrides it. This could be useful as an end-point for a super-call in a framework that uses cooperative multiple-inheritance.
abc.
abstractproperty
(
[
fget
[
,
fset
[
,
fdel
[
,
doc
]
]
]
]
)
¶
子类化的内置
property()
,指示抽象特性。
Using this function requires that the class’s metaclass is
ABCMeta
或是来自它的派生。拥有元类的类派生自
ABCMeta
cannot be instantiated unless all of its abstract methods and properties are overridden. The abstract properties can be called using any of the normal ‘super’ call mechanisms.
用法:
class C: __metaclass__ = ABCMeta @abstractproperty def my_abstract_property(self): ...
This defines a read-only property; you can also define a read-write abstract property using the ‘long’ form of property declaration:
class C: __metaclass__ = ABCMeta def getx(self): ... def setx(self, value): ... x = abstractproperty(getx, setx)
脚注
C++ programmers should note that Python’s virtual base class concept is not the same as C++’s.