Python 抽象基类的理解
一、抽象基类的特点:
1.规定继承类必须具有抽象基类指定的方法
2.抽象基类无法实例化
以上两个特点,主要用于接口设计
注意:Python中并没有提供抽象类与抽象方法,但是提供了内置模块abc来模拟实现抽象类
二、使用场景:
1.判断某个对象的类型:
class ColorObj(object):
"""创建一个颜色的类"""
def __init__(self, color_list):
"""初始化方法"""
self.color = color_list
def __len__(self):
return len(self.color)
color = ColorObj(['red', 'yellow', 'blue'])
from collections.abc import Sized
result = isinstance(color, Sized)
print(result)
# 输出结果: True
-
isinstance 用来判断一个对象的实例
,Color都没有继承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
解释:这个Sized的抽象基类,它会继承metaclass=ABCMeta, 并且@abstractmethod 抽象方法,关键判断它是否有__ len __ 方法在于下面的 __ subclasshook __ 魔法方法。
2.强制子类必须实现某些方法:
-
首先看一下,上面所说的特点
抽象基类无法实例化
:import abc class BaseObj(metaclass=abc.ABCMeta): """基类""" @abc.abstractmethod # 给该方法添加装饰器 def get(self, value): print(value) @abc.abstractmethod def set(self, key, value): print(key, value) base_obj = BaseObj() # 实例化BaseObj的时候报错 print(base_obj) # 报错信息: Traceback (most recent call last): File "C:/Users/lh9/PycharmProjects/request/Python魔法函数.py", line 121, in <module> base_obj = BaseObj() TypeError: Can't instantiate abstract class BaseObj with abstract methods get, set
-
强制子类实现的方法:
class BaseObj(metaclass=abc.ABCMeta): """基类""" @abc.abstractmethod def get(self, value): print(value) @abc.abstractmethod def set(self, key, value): print(key, value) class Dog(BaseObj): def get(self, value): print(value) dog = Dog() print(dog.get('fe_cow')) # 输出结果会报错: Traceback (most recent call last): File "C:/Users/lh9/PycharmProjects/request/Python魔法函数.py", line 127, in <module> dog = Dog() TypeError: Can't instantiate abstract class Dog with abstract methods set
报错原因:因为我们继承的BaseObj类中,get、set方法都添加了装饰器@abc.abstractmethod,说明
要继承BaseObj的子类,必须要实现get、set方法
,否则会报错。class BaseObj(metaclass=abc.ABCMeta): """基类""" @abc.abstractmethod def get(self, value): print(value) @abc.abstractmethod def set(self, key, value): print(key, value) class Dog(BaseObj): def get(self, value): print(value) return value def set(self, key, value): pass dog = Dog() print(dog.get('fe_cow')) # 输出结果: fe_cow fe_cow
三、collection.abc模块常用的抽象基类:
__all__ = ["Awaitable", "Coroutine",
"AsyncIterable", "AsyncIterator", "AsyncGenerator",
"Hashable", "Iterable", "Iterator", "Generator", "Reversible",
"Sized", "Container", "Callable", "Collection",
"Set", "MutableSet",
"Mapping", "MutableMapping",
"MappingView", "KeysView", "ItemsView", "ValuesView",
"Sequence", "MutableSequence",
"ByteString",
]
感兴趣的可以看看这些源码