python -abc模块学习总结
python 没有提供抽象类与抽象方法。ABC(Abstract Base Class)模块提供了在Python中定义抽象类的方法。
abc模块有以下两个主要功能:
某种情况下,判定某个对象的类型,如:
isinstance(a, MyABC), issubclass(a, MyABC)
强制子类必须实现某些方法,即ABC类的派生类
abc.ABC
辅助类 ,可以不用关心元类的概念,直接继承就有了ABCMeta元类,使用时注意元类冲突。
abc.ABCMeta
该类用来定义抽象类的元类。使用该元类来定义一个抽象类。
定义一个抽象基类的方法是将一个类的元类设置为abc.ABCMeta。
具体化抽象基类的两种方式:
1、通过抽象基类 ABCMeta 的 register 方法注册。
from abc import ABCMeta,abstractmethod
class MyABC(metaclass=ABCMeta):
@abstractmethod
def amtest(self):
"""abstractf method"""
class RegisterImpl:
def amtest(self):
print('RegisterImpl')
MyABC.register(RegisterImpl)
2、通过继承的方式。
from abc import ABCMeta,abstractmethod
class MyABC(metaclass=ABCMeta):
@abstractmethod
def amtest(self):
"""abstractf method"""
class InheritImpl(MyABC):
def amtest(self):
print('InheritImpl')
使用直接继承的方式,如果子类中没有完全实现相应的虚接口,那么在执行的时候就会报错,但是如果使注册的方式,就没有该限制。
abstractmethod
@abstractmethod之后,从新的一行开始定义相应的方法。
实现的方法就是一个抽象的方法,有点像Java中的接口。子类继承之后,如果需要用到的这个方法则必须用新的方法将其实现。
该@abstractmethod装饰应仅在类体中使用,并且仅用于一个其元类是(衍生自)ABCMeta。不支持将动态方法添加到类,或在创建方法或类后尝试修改其抽象状态。该@abstractmethod仅影响使用常规继承派生的子类; 使用register()方法注册的“虚拟子类”不受影响。
from abc import ABCMeta, abstractmethod
class A(metaclass=ABCMeta):
@abstractmethod
def foo(self): pass
A() # raises TypeError
class B(A):
pass
B() # raises TypeError
class C(A):
def foo(self): print(42)
C() # works
@abstractproperty
与抽象方法类似,继承抽象属性(使用修饰符语法或更长格式声明)的子类无法实例化,除非它用具体属性重写抽象属性。
class C(metaclass=ABCMeta):
# A read-only property:
@abstractproperty
def readonly(self):
return self.__x
# A read-write property (cannot use decorator syntax):
def getx(self):
return self.__x
def setx(self, value):
self.__x = value
x = abstractproperty(getx, setx)