定义一个接口或者是抽象基类

一,老样子,抛出一个问题:我们想定义一个类作为接口或者是抽象基类,如何在此之上执行类型检查并确保子类中实行特定的规范

要定义抽象基类:可以考虑使用abc模块:

  

from abc import ABCMeta, abstractmethod

class Mystream(metaclass=ABCMeta)  # 必须要继承
    @abstractmethod
    def read(self, maxbytes=-1):
        pass
        
    @abstractmethod
    def write(self, data):
        pass

抽象基类的核心特征就是不能直接实例化。如果尝试这么做的话,错误提示:

a = Mystream()

# TypeError: can't instantiate abstract class
# Mystream with abstract methods read, write

抽象基类是用来给其他类当做基类来使用的,这些子类需要实现积累中的那些方法。示例如下:

class Stream(Mystream):
    
    def read(self, maxbytes=-1):
        pass

    def write(self, data):
        pass

划重点来了!

假如子类中没有read或者write方法,那么直接报错!

抽象基类的主要用途是强制规定所需的编程接口。例如:一种看待Mystream基类的方式就是在高层次上指定一个接口规范,使其准许读取和写入数据。显式检查这个接口的代码可以写成如下状态。

def Mycheck(obj, stream):
    if not isinstance(stream, Mystream):
        raise TypeError('Expected an Mystream')
……

我们可能会认为这种形式的类型检查只有在子类化抽象基类(ABC)时才能工作,但是抽象基类也容许其他的类向其注册,然后实现所需的接口。例如我们可以这样做:

import io

Mystream.register(io.IOBase)

# 随意打开一个普通文件进行类型检查
f = open('foo.txt')

isinstance(f, Mystream)

# return True

应该提到的是,@abstractmethod也同样可以施加到静态方法、类方法和@property属性上,但是!!!!!一定要注意顺序!!!

@abstractmethod必须紧挨着函数定义!!

示例如下:

 from abc import ABCMtea, abstractmethod

class A(metaclass=ABCMeta):
    @property
    @abstractmethod
    def name(self):
        pass

    @classmethod
    @abstractmethod
    def method(cls):
        pass

    @staticmethod
    @abstractmethod
    def method2():
        pass

    @name.setter
    @abstractmethod
    def name(self, value):
        pass

猜你喜欢

转载自www.cnblogs.com/zhoulixiansen/p/9130663.html