Python是动态语言,动态语言是没有变量类型的,在Python中变量只是一个符号而已,是可以指向任何类型的对象
不推荐使用抽象基类
1.检查某个类中是否存在某个方法
class Company(object):
def __init__(self, employee_list):
self.employee = employee_list
def __len__(self):
return len(self.employee)
com = Company(['123', '234'])
print(hasattr(com, '__len__')) # True
以上为普通方法,以下为抽象基类
2.在某些情况下希望判断某个对象的类型
from collections.abc import Sized
print(isinstance(com, Sized)) # True
collections.abc中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.强制某个子类必须实现某些方法
例如:
实现一个Web框架,继承cache(redis, cache, memorycache)
需要设计一个抽象基类,指定子类必须实现某些方法首先实现一个基类
class CacheBase():
def get(self, key):
raise NotImplementedError
def set(self, key, value):
raise NotImplementedError
class RedisCache(CacheBase):
pass
redis_cache = RedisCache()
redis_cache.set('key', 'value')
# 运行结果,会执行基类中的方法并抛出异常
class RedisCache(CacheBase):
def set(self, key, value):
pass
redis_cache = RedisCache()
redis_cache.set('key', 'value')
# 如果子类中实现了基类中的方法,则不会抛出异常
使用abc抽象基类实现
import abc
class CacheBase(metaclass=abc.ABCMeta):
@abc.abstractmethod
def get(self, key):
pass
@abc.abstractmethod
def set(self, key, value):
pass
class RedisCache(CacheBase):
pass
redis_cache = RedisCache()
# 使用abc抽象基类实现,如果子类不实现基类中的方法,在实例化子类的时候会报错
class RedisCache(CacheBase):
def get(self, key):
pass
def set(self, key, value):
pass
# 使用abc抽象基类实现,实现基类中的方法,在实例化子类的时候不会报错