555 字
3 分钟
第11章-抽象类
2020-03-30

第11章-抽象类#

[toc]

ABC类#

python中并没有提供抽象类与抽象方法, 但是提供了内置模块**abc(abstract base class)**来模拟实现抽象类。

可以通过abc将基类声明为抽象类的方式,然后注册具体类作为这个基类的实现。

假设我们在写一个关于动物的代码。涉及到的动物有鸟,狗,牛。

首先鸟,狗,牛都是属于动物的。既然是动物那么肯定需要吃饭,发出声音。

但是具体到鸟,狗,牛来说吃饭和声音肯定是不同的。

需要具体去实现鸟,狗,牛吃饭和声音的代码。

概括一下抽象基类的作用:定义一些共同事物的规则和行为

例子:

class Animal(object):
def eat(self):
raise NotImplementedError
def voice(self):
raise NotImplementedError
class Dog(Animal):
def voice(self):
print('wow....')
class Bird(Animal):
def voice(self):
print('jiji....')
class Cow(Animal):
def voice(self):
print('Oh.....')
if __name__ == "__main__":
d = Dog()
d.voice()
d.eat() # raise NotImplementedError

这样实现有个缺点,就是只有子类调用eat方法的时候才会报错。

子类是可以正常实例化的。

但是你能够想象鸟,狗,牛不会吃饭么? 如果不会吃饭那肯定不算是动物了。

所以正常的实现应该是如果没有实现eat方法,实例化就应该是失败的。

那么这里就要用到抽象基类的一般使用方法.

import abc
class Animal(object):
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def eat(self):
return
@abc.abstractmethod
def voice(self):
return
class Dog(Animal):
def voice(self):
print('wow....')
def eat(self):
print("Dog eat...")
class Bird(Animal):
def voice(self):
print('jiji....')
def eat(self):
print("Bird eat...")
class Cow(Animal):
def voice(self):
print('Oh.....')
def eat(self):
print("Cow eat...")
if __name__ == "__main__":
d = Dog()
b = Bird()
c = Cow()
d.voice()
d.eat()
b.voice()
b.eat()
c.voice()
c.eat()

返回结果:

wow....
Dog eat...
jiji....
Bird eat...
Oh.....
Cow eat...

使用注册的方式:

from abc import ABCMeta, abstractmethod
class Animal(metaclass=ABCMeta):
@abstractmethod
def eat(self):
return
@abstractmethod
def voice(self):
return
class Dog(object):
def voice(self):
print('wow....')
def eat(self):
print("Dog eat...")
# 使用注册方式,必须两个方法都要写,否则会报错
Animal.register(Dog)
if __name__ == "__main__":
d = Dog()
d.voice()
d.eat()

继承和注册这两种方法有什么区别呢?

animals.py

from abc import ABCMeta, abstractmethod
class Animal(metaclass=ABCMeta):
@abstractmethod
def eat(self):
return
@abstractmethod
def voice(self):
return

sub_class.py

from animals import Animal
class Dog(Animal):
def voice(self):
print('wow....')
def eat(self):
print("Dog eat...")
print('subclass=', issubclass(Dog, Animal))
print('Instance=', isinstance(Dog(), Animal))

abc_register.py

from animals import Animal
class Dog(object):
def voice(self):
print('wow....')
def eat(self):
print("Dog eat...")
Animal.register(Dog)
print('subclass=', issubclass(Dog, Animal))
print('Instance=', isinstance(Dog(), Animal))
第11章-抽象类
https://blog.zhequtao.com/posts/python/流畅的python/第11章-抽象类/
作者
阿俊
发布于
2020-03-30
许可协议
CC BY-NC-SA 4.0

相关阅读