资讯专栏INFORMATION COLUMN

Python模块文档学习之抽象基类abc模块

lauren_liuling / 620人阅读

摘要:里面关于抽象类的相关介绍中并没有提供抽象类与抽象方法,但是提供了内置模块来模拟实现抽象类。主要类或函数这是用来生成抽象基础类的元类。继承方式中的抽象类模块定义了几个抽象类。

PEP里面关于抽象类的相关介绍:https://www.python.org/dev/pe...
python中并没有提供抽象类与抽象方法,但是提供了内置模块abc(abstract base class)来模拟实现抽象类。
主要类或函数:
abc.ABCMeta 这是用来生成抽象基础类的元类。由它生成的类可以被直接继承。
abc.ABC辅助类,让你可以不用关心元类概念,直接继承它,就有了ABCMeta元类。使用时注意元类冲突
@abc.abstractmethod 定义抽象方法,除了这个装饰器,其余装饰器都被deprecated了。

from abc import ABCMeta

class MyABC(metaclass=ABCMeta):
    pass

MyABC.register(tuple)

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

上面这个例子中,首先生成了一个MyABC的抽象基础类,然后再将tuple变成它的虚拟子类。然后通过issubclass或者isinstance都可以判断出tuple是不是出于MyABC类。
另外,也可以通过复写__subclasshook__(subclass)来改变issubclass或者isinstance的行为,__subclasshook__(subclass)必须定义为classmethod

class Foo:
    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.abstractmethod将方法声明为抽象方法。
具体化抽象类可以有两种方式,一种通过注册(register),另外一种通过继承。
上面介绍的是注册方式,
注册方式的缺点:不会出现在类的MRO (Method Resolution Order),故而也不能通过super()来调用抽象方法。当没有实现抽象方法时,实例化时候不会报错,只有在调用时候才会报错。

下面介绍继承方式:
继承方式的优点:直接从抽象基类派生子类有一个好处,除非子类实现抽象基类的抽象方法,否则子类不能实例化。

继承方式:

import abc

class PluginBase(metaclass= abc.ABCMeta):
    #__metaclass__ = abc.ABCMeta
    
    @abc.abstractmethod
    def load(self, input):
        """Retrieve data from the input source and return an object."""
        return
    
    @abc.abstractmethod
    def save(self, output, data):
        """Save the data object to the output."""
        return
        
class SubclassImplementation(PluginBase):
    
    def load(self, input):
        return input.read()
    
    def save(self, output, data):
        return output.write(data)
 
if __name__ == "__main__":
    print "Subclass:", issubclass(SubclassImplementation, PluginBase)
    print "Instance:", isinstance(SubclassImplementation(), PluginBase)
collections中的抽象类

collections.abc模块定义了几个抽象类。
具体请看文档。

参考:
https://docs.python.org/3/lib...
https://www.python.org/dev/pe...
https://my.oschina.net/u/2253...
http://yansu.org/2013/06/09/l...
http://www.cnblogs.com/Securi...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/38300.html

相关文章

  • Python基础之接口——从协议到抽象基类

    摘要:本文重点协议是中非正式的接口了解抽象基类的基本概念以及标准库中的抽象基类掌握抽象基类的使用方法。三抽象基类的使用通过继承声明抽象基类声明抽象基类最简单的方式是继承或其他抽象基类注意在之间,继承抽象基类的语法是。 导语:本文章记录了本人在学习Python基础之面向对象篇的重点知识及个人心得,打算入门Python的朋友们可以来一起学习并交流。 本文重点: 1、协议是Python中非正式的接...

    TwIStOy 评论0 收藏0
  • Python习之路30-接口:从协议到抽象基类

    摘要:本篇内容将从鸭子类型的动态协议,逐渐过渡到使接口更明确能验证实现是否符合规定的抽象基类。抽象基类介绍完动态实现接口后,现在开始讨论抽象基类,它属于静态显示地实现接口。标准库中的抽象基类从开始,标准库提供了抽象基类。 《流畅的Python》笔记。本篇是面向对象惯用方法的第四篇,主要讨论接口。本篇内容将从鸭子类型的动态协议,逐渐过渡到使接口更明确、能验证实现是否符合规定的抽象基类(Abst...

    LucasTwilight 评论0 收藏0
  • 流畅的python读书笔记-第11章-接口:从协议到抽象基类

    摘要:自己定义的抽象基类要继承。抽象基类可以包含具体方法。这里想表达的观点是我们可以偷懒,直接从抽象基类中继承不是那么理想的具体方法。 抽象基类 抽象基类的常见用途: 实现接口时作为超类使用。 然后,说明抽象基类如何检查具体子类是否符合接口定义,以及如何使用注册机制声明一个类实现了某个接口,而不进行子类化操作。 如何让抽象基类自动识别任何符合接口的类——不进行子类化或注册。 接口在动态类...

    Kyxy 评论0 收藏0
  • python标准库习之zipfile模块

    摘要:模块里有两个非常重要的分别是和。返回一个对象,它包括文件的详细信息。将文档内的指定文件解压到当前目录。为文件路径,为添加到文档之后保存的名称参数表示压缩方法,它的值可以是或。预留字段,当前实现总是返回。 ZipFile模块里有两个非常重要的class, 分别是 ZipFile和ZipInfo。ZipFile是主要的类,用来创建和读取zip文件,而ZipInfo是存储的zip文件的每个文...

    Magicer 评论0 收藏0
  • Python习之路25-使用一等函数实现设计模式

    摘要:本篇主要讲述中使用函数来实现策略模式和命令模式,最后总结出这种做法背后的思想。 《流畅的Python》笔记。本篇主要讲述Python中使用函数来实现策略模式和命令模式,最后总结出这种做法背后的思想。 1. 重构策略模式 策略模式如果用面向对象的思想来简单解释的话,其实就是多态。父类指向子类,根据子类对同一方法的不同重写,得到不同结果。 1.1 经典的策略模式 下图是经典的策略模式的U...

    econi 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<