Why Python has abstract base class

栏目: Python · 发布时间: 7年前

内容简介:Why Python has abstract base class

抽象基类(Abstract base classes)并不是 Python 本身的语言特性,而是在标准库中提供了一种支持。关于抽象基类, Python Glossary 中定义如下

Abstract base classes complement duck-typing by providing a way to define interfaces when other techniques like hasattr() would be clumsy or subtly wrong (for example with magic methods). ABCs introduce virtual subclasses, which are classes that don’t inherit from a class but are still recognized by isinstance() and issubclass(); see the abc module documentation. Python comes with many built-in ABCs for data structures (in the collections.abc module), numbers (in the numbers module), streams (in the io module), import finders and loaders (in the importlib.abc module). You can create your own ABCs with the abc module.

一般定义抽象基类可以使用 abc.ABCMeta 这个元类,通过 register() 方法能将不相关的具体类(包含 built-in class)及其他抽象类注册为虚子类(virtual subclasses)。

[virtual subclass 这个概念好像只有在 Python 中有提到] issubclass() 会认为他们之间具有子类关系,但抽象基类并不会出现在被注册类的 MRO 中,也不会调用到抽象基类中定义的方法。当然也可以不用费劲的通过 register() 一个个进行注册,能够通过 __subclasshook__() 来控制 issubclass() 的行为。普通类定义 __subclasshook__()

并不会被触发

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.

演示代码

In [17]: int.__mro__  
Out[17]: (int, object)

In [18]: bool.__mro__  
Out[18]: (bool, int, object)

In [19]: class A(metaclass=abc.ABCMeta):  
    ...:     pass
    ...:

In [20]: A.register(int)  
Out[20]: int

In [21]: int.__mro__  
Out[21]: (int, object)

In [22]: bool.__mro__  
Out[22]: (bool, int, object)

In [23]: issubclass(int, A)  
Out[23]: True

In [24]: issubclass(bool, A)  
Out[24]: True

通常而言,抽象基类就是定义了一系列子类必须要实现的东西,相当于一种契约,如果没有实现这种契约是不能被实例化的。Python 也是如此,不过这种概念相对而言意义不大,因为 Python 可以通过自省(instrospect)和 EAFP 灵活地判断对象是否满足契约。不过在 Python 中抽象基类还有一个作用,那便是用于 duck-typing 中(Glossary 中也提到抽象基类为 duck-typing 提供了扩充)。在这种编程风格中,并不关注对象的类型,而是关注对象是否具有某些行为。而抽象基类可以看做提供了一系列行为的集合。如果你实现了这些行为,便可以看做是这个抽象基类的 virtual subclass

In [35]: class P:  
    ...:     def __iter__(self):
    ...:         pass
    ...:     def __contains__(self, item):
    ...:         pass
    ...:     
    ...:     

# 触发 Container 的 __subclasshook__
In [36]: issubclass(P, Container)  
Out[36]: True

In [37]: issubclass(P, Iterable)  
Out[37]: True

我们可以通过抽象基类来检测对象是否满足条件,正如 duck-typing 所形容的,实现了 __contains__() 的类型都是 Container; 实现了 __iter__() 的类型都是 Iterable。因此可以进行更友好的行为检测,而不是像下面这样松散的代码

if hasattr(P, '__iter__') and hasattr(P, '__contains__'):  
    pass
# or
if all(map(lambda attr: hasattr(P, attr), ['__iter__', '__contains__'])):  
    pass

Reference

Why use Abstract Base Classes in Python?


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

看见未来

看见未来

余晨 / 浙江大学出版社 / 2015-4-15 / 59.00元

【内容简介】 这是互联网群星闪耀的时代,巨人们用最尖端的技术和自成体系的哲学改变着我们的生活,甚至影响了整个世界和人类的历史进程。在这个时代,没有人可以避开互联网的渗透。互联网早已不是简单的技术变革,人们正试图赋予其精神和内涵,以期互联网能更好地为人类所用。 本书中作者 面对面地采访了包括马克·扎克伯格、埃隆·马斯克、杨致远、凯文·凯利、克里斯·安德森、罗伯特·希勒、迈克尔·莫瑞茨、凯......一起来看看 《看见未来》 这本书的介绍吧!

html转js在线工具
html转js在线工具

html转js在线工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具