我试图了解使用抽象基类的好处。考虑以下两段代码:
抽象基类:
from abc import ABCMeta, abstractmethod, abstractproperty
class CanFly:
__metaclass__ = ABCMeta
@abstractmethod
def fly(self):
pass
@abstractproperty
def speed(self):
pass
class Bird(CanFly):
def __init__(self):
self.name = 'flappy'
@property
def speed(self):
return 1
def fly(self):
print('fly')
b = Bird()
print(isinstance(b, CanFly)) # True
print(issubclass(Bird, CanFly)) # True
普通继承:
class CanFly(object):
def fly(self):
raise NotImplementedError
@property
def speed(self):
raise NotImplementedError()
class Bird(CanFly):
@property
def speed(self):
return 1
def fly(self):
print('fly')
b = Bird()
print(isinstance(b, CanFly)) # True
print(issubclass(Bird, CanFly)) # True
如您所见,这两种方法都支持使用isinstance
和的变形issubclass
。
现在,我知道的一个区别是,如果您尝试实例化抽象基类的子类而不覆盖所有抽象方法/属性,那么您的程序将失败。但是,如果您使用普通继承 with NotImplementedError
,则在您实际调用相关方法/属性之前,您的代码不会失败。
除此之外,使用抽象基类有何不同?