定义接口或者抽象基类

针对接口编程,而不是针对实现编程,这是四人组的经典名作《设计模式 可复用面向对象软件的基础》的第一个原则。

你想定义一个接口或抽象类,并且通过执行类型检查来确保子类实现了某些特定的方法。

解决方案:

使用 abc 模块可以很轻松的定义抽象基类

from abc import ABCMeta, abstractmethod

class IStream(metaclass=ABCMeta):
    @abstractmethod
    def read(self, maxbytes=-1):
        pass

    @abstractmethod
    def write(self, data):
        pass

 抽象类的一个特点是它不能直接被实例化,比如你想像下面这样做是不行的:

a = IStream()
>>>TypeError: Can't instantiate abstract class IStream with abstract methods read, write

 抽象类的目的就是让别的类继承它并实现特定的抽象方法:

class SocketStream(IStream):
    def read(self, maxbytes=-1):
        pass

    def write(self, data):
        pass

 抽象基类的一个主要用途是在代码中检查某些类是否为特定类型,实现了特定接口:

def serialize(obj, stream):
    if not isinstance(stream, IStream):
        raise TypeError('Expected an IStream')
    pass

@abstractmethod 还能注解静态方法、类方法和 properties 。 你只需保证这个注解紧靠在函数定义前即可

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

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

    @classmethod
    @abstractmethod
    def method1(cls):
        pass

    @staticmethod
    @abstractmethod
    def method2():
        pass

 

posted @ 2018-12-27 13:52  家迪的家  阅读(368)  评论(0)    收藏  举报