ABC,Abstract Base Class(抽象基类),主要定义了基本类和最基本的抽象方法,可以为子类定义共有的API,不需要具体实现。相当于是Java中的接口或者是抽象类。
抽象基类可以不实现具体的方法(当然也可以实现,只不过子类如果想调用抽象基类中定义的方法需要使用super())而是将其留给派生类实现。
然而在Python的2.x 和Python3.x 中抽象类的使用确有不同
本人就因为在2.x版本中运行3.x写法的代码,总是报错
Python ImportError: cannot import name ABC
最后才定位到这个原因
在Python3.4中,声明抽象基类最简单的方式是子类话abc.ABC;Python3.0到Python3.3,必须在class语句中使用metaclass=ABCMeta;Python2中使用__metaclass__=ABCMeta
Python2.x中
在类中引用__metaclass__ = ABCMeta
但在定义时不继承
abc 模块中没有ABC基类 只有 ABCMeta, abstractmethod
import sys
from abc import ABCMeta, abstractmethod
class Base():
__metaclass__ = ABCMeta
@abstractmethod
def func(self):
'''Implement in subclass'''
class MyClass(Base):
def func(self):
print(“my class in 2.x”)
obj = MyClass()
obj.func()
Python3.0 - Python3.3中
必须在class语句中使用metaclass=ABCMeta;
即在定义时显式继承
abc 模块中没有ABC基类 只有 ABCMeta, abstractmethod
import sys
from abc import ABCMeta, abstractmethod
class Base(metaclass = abc.ABCMeta):
@abstractmethod
def func(self):
'''Implement in subclass'''
class MyClass(Base):
def func(self):
print(“my class in 2.x”)
obj = MyClass()
obj.func()
Python3.4及以上版本中
abc 模块中有ABC基类,直接显式继承即可
import sys
from abc import ABC,abstractmethod
class Base(ABC):
@abstractmethod
def func(self):
'''Implement in subclass'''
class MyClass(Base):
def func(self):
print("my class in 3.x")
obj = MyClass()
obj.func()
最后给出一个兼容后的代码
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import sys
if sys.version > '3':
from abc import ABC,abstractmethod
else:
from abc import ABCMeta, abstractmethod
if sys.version > '3':
class Base(ABC):
@abstractmethod
def func(self):
'''Implement in subclass'''
else:
class Base():
__metaclass__ = ABCMeta
@abstractmethod
def func(self):
'''Implement in subclass'''
class MyClass(Base):
def func(self):
print("my class")
obj = MyClass()
obj.func()