1.抽象基类的定义
抽象基类(abstract base class,ABC):抽象基类就是类里定义了纯虚成员函数的类,纯虚函数只提供了接口,并没有具体实现。
2.抽象基类的特点
不能被实例化
抽象基类不能被实例化(不能创建对象),通常是作为基类供子类继承,子类中重写虚函数,实现具体的接口。
子类必须实现抽象基类的方法
抽象基类就是定义各种方法而不做具体实现的类,任何继承自抽象基类的类必须实现这些方法,否则无法实例化。
3.抽象基类应用场景
3.1 检查某个类中是否有某种方法
判断 Demo中 是否 含有 __len__魔法方法
class Demo(object): def __init__(self,list): self.list = list def __len__(self): return len(self.list) d = Demo(["CW","ls",'age']) from collections.abc import Sized #导入模块collections.abc的Sized类 print(hasattr(Sized,"__len__")) # 判断d的内部 是否含有__len__ ,返回值为布尔值,结果为true print(isinstance(d,Sized)) # 检查d是否Sized类型 结果为:True
Sized源码如下:
class Sized(metaclass=ABCMeta): __slots__ = () @abstractmethod def __len__(self): return 0 @classmethod def __subclasshook__(cls, C): if cls is Sized: return _check_methods(C, "__len__") return NotImplemented
3.2 强制子类必须实现父类的方法
3.2.1 方法一:主动抛出异常
如下实例,子类RedisBase中未重写crea方法,在实例化子类RedisBase,没有报错,在调用crea()方法时报错:
class CacheBase(object):
def dele(self):
raise NotImplementedError
def crea(self):
raise NotImplementedError
class RedisBase(CacheBase):
def dele(self):
print('I will delete')
# def crea(self):
# print('I will create')
r = RedisBase()
r.crea() #raise NotImplementedError
r.dele()
3.2.2 方法二:抽象基类实现
如下实例中,子类RedisBase中未重写crea方法,在实例化子类RedisBase时就报错:
import abc
class BaseClass(metaclass=abc.ABCMeta):
@abc.abstractmethod
def dele(self):
pass
@abc.abstractmethod
def crea(self):
pass
class SubClass(BaseClass):
def dele(self):
print('I will delete')
# def crea(self):
# print('I will create')
r = SubClass() # TypeError: Can't instantiate abstract class SubClass with abstract methods crea
r.dele()
r.crea()
3.2.3 两种方法对比
主动抛出异常 :调用时才会检测
抽象基类 : 实例化的时候检测



