python 抽象方法 抽象类实现

抽象基类

ABC 是一些不能被实例化的类。Java 或 C++ 语言的程序员应该对此概念十分熟悉。Python 3 添加了一个新的框架 —abc— 它提供了对 ABC 的支持。

这个 abc 模块具有一个元类(ABCMeta)和 修饰符(@abstractmethod 和 @abstractproperty)。如果一个 ABC 具有一个 @abstractmethod或 @abstractproperty,它就不能被实例化,但必须在一个子类内被覆盖。比如,如下代码:

>>>from abc import *
>>>class C(metaclass = ABCMeta): pass
>>>c = C()

这些代码是可以的,但是不能像下面这样编码:

>>>from abc import *
>>>class C(metaclass = ABCMeta): 
...    @abstractmethod
...    def absMethod(self):
...        pass
>>>c = C() 
Traceback (most recent call last):
File "", line 1, in 
TypeError: Can't instantiate abstract class C with abstract methods absMethod

更好的做法是使用如下代码:

>>>class B(C):
...    def absMethod(self):
...        print("Now a concrete method")
>>>b = B()
>>>b.absMethod()
Now a concrete method

ABCMeta 类覆盖属性 __instancecheck__ 和 __subclasscheck__,借此可以重载内置函数 isinstance() 和 issubclass()。要向 ABC 添加一个虚拟子类,可以使用 ABCMeta 提供的 register() 方法。如下所示的简单示例:

>>>class TestABC(metaclass=ABCMeta): pass
>>>TestABC.register(list)
>>>TestABC.__instancecheck__([])
True

它等同于使用 isinstance(list, TestABC)。您可能已经注意到 Python 3 使用 __instancecheck__,而非 __issubclass__,使用__subclasscheck__,而非 __issubclass__,这看起来更为自然。若将参数 isinstance(subclass, superclass) 反转成,比如superclass.__isinstance__(subclass),可能会引起混淆。可见,语法 superclass.__instancecheck__(subclass) 显然更好一点。

在 collections 模块内,可以使用几个 ABC 来测试一个类是否提供了特定的一个接口:

>>>from collections import Iterable
>>>issubclass(list, Iterable)
True

表 1 给出了这个集合框架的 ABC。

表 1. 这个集合框架的 ABC
ABC Inherits
Container  
Hashable  
Iterable  
Iterator Iterable
Sized  
Callable  
Sequence SizedIterableContainer
MutableSequence Sequence
Set SizedIterableContainer
MutableSet Set
Mapping SizedIterableContainer
MutableMapping Mapping
MappingView Sized
KeysView MappingViewSet
ItemsView MappingViewSet
ValuesView MappingView

集合

集合框架包括容器数据类型、双端队列(即 deque)以及一个默认的字典(即 defaultdict)。一个 deque 支持从前面或后面进行追加和弹出。defaultdict 容器是内置字典的一个子类,它(根据 Python 3 文档)“覆盖一个方法并添加一个可写的实例变量。”除此之外,它还充当一个字典。此外,集合框架还提供了一个数据类型工厂函数 namedtuple()

ABC 类型层次结构

Python 3 现支持能代表数值类的 ABC 的类型层次结构。这些 ABC 存在于 numbers 模块内并包括 Number、 ComplexReal、 Rational 和 Integral。图 1 显示了这个数值层次结构。可以使用它们来实现您自己的数值类型或其他数值 ABC。

图 1. 数值层次结构

数值塔(numerical tower)

Python 的数值层次结构的灵感来自于 Scheme 语言的数值塔。

新模块 fractions 可实现这个数值 ABC Rational。此模块提供对有理数算法的支持。若使用 dir(fractions.Fraction),就会注意到它具有一些属性,比如 imag、 real 和 __complex__。根据数值塔的原理分析,其原因在于 Rationals 继承自 Reals,而 Reals 继承自 Complex


你可能感兴趣的:(Python)