简介
面向对象与面向过程
面向过程:例如旅游,从四川到广东,我们需要先到四川、再到湖南、再到湖北,最后到广东,不需要关心交通方式,重点是过程。
面向对象:例如旅游,从四川到广东,我们选择火车或走路到广东,不需要关心会经过的地方,重点是交通方式(即对象)。
抽象类
如果说类是从一堆对象中抽取相同的内容而来的,那么抽象类就是从一堆类中抽取相同的内容而来的,内容包括数据属性和函数属性。
比如我们旅游景区可以分为3A级景区类,4A级景区类,5A级景区类,从这景区类中取相同的内容就是旅游景区这个抽象类。我们去旅游时,就会选择某个具体的3A级景点、4A级景点、5A级景点,比如世界之窗、广州小蛮腰,这就是实例化。
抽象类代码举例
python定义抽象类例子如下。例子中ExtractorContext类不能被实例化,只能被继承,且子类必须实现抽象方法,这一点与接口有点类似。
class ExtractorContext(metaclass=ABCMeta):
@abstractmethod
def get_ua(self, pc: bool) -> json:
pass
@abstractmethod
def get_proxy(self,tid=None)->str:
pass
class Node(metaclass=ABCMeta):
def __init__(self):
pass
@abstractmethod
def get_state(self) -> NodeState:
pass
E=ExtractorContext() <---报错
接口类
python中没有接口这个概念,我们可以使用抽象类模拟接口。在接口中,任何方法都只是一种规范,具体的功能需要子类实现。在抽象类中,我们可以定义抽象方法去模拟接口,实现规范化。
接口类代码举例
python继承抽象类例子如下。 例子中PandoraNode类继承了ExtractorContext抽象类和Node抽象类,并示例化了抽象类中的所有方法,否则会报错‘TypeError: Can’t instantiate abstract class PandoraMinNode with abstract methods xxx’。通过报错,强制要求我们实现抽象类中的全部方法,这点与接口的规范性类似。
class PandoraNode(ExtractorContext, Node):
def get_ua(self, pc: bool) -> dict:
return UserAgent().get_useragent(pc)
def get_proxy(self,tid=None):
return get_ip(tid)
def get_state(self) -> NodeState:
state = NodeState(self.__runtime(), self.is_zkp, self.is_stop, self.is_free, self.type_id, self.ip)
return state
多继承问题
在继承抽象类的过程中,我们应该尽量避免多继承;而在继承接口的时候,我们反而鼓励使用多继承接口。在接口类代码举例中,我们就使用到了多继承。
完整程序
代码实现逻辑
使用python的abc模块定义抽象类class(meta=ABCMeta),使用装饰器@abstractmethod定义抽象方法xx,其他类如果继承了抽象类class,其他类中就都需要有一个xx方法,如果没有就会报错,即规范化。统一爬虫接口,我们继承抽象类class后,我们的爬虫环境接口名就必须用xx,这就是接口类(抽象类的用途)。
class ExtractorContext(metaclass=ABCMeta):
@abstractmethod
def get_ua(self, pc: bool) -> json:
pass
@abstractmethod
def get_proxy(self, tid=None) -> str:
pass
class Node(metaclass=ABCMeta):
def __init__(self):
pass
@abstractmethod
def get_state(self) -> NodeState:
pass
class PandoraNode(ExtractorContext, Node):
def get_ua(self, pc: bool) -> dict:
return UserAgent().get_useragent(pc)
def get_proxy(self, tid=None):
return get_ip(tid)
def get_state(self) -> NodeState:
state = NodeState('xx','xx','xx','xx','xx','xx')
return state
E=ExtractorContext() # 报错
P=PandoraNode() # 正确
P.get_state() # 正确
P.get_ua(False) # 正确
P.get_proxy('XX') # 正确