文章目录
前言
大家在看到langchain-chatchat这里的时候可能会有些疑惑,这个ABC感觉很神奇,
追踪进去的时候可能感觉更疑惑了。
其实这是python实现抽象类的一种方式。我们今天就来学习python的一个重要知识点 - 抽象类
一、抽象类是什么?在python中如何定义呢
1. 定义
抽象类是一种特殊的类,它无法被实例化,只能被用作其他类的基类。抽象类主要用于定义接口和规范子类的行为。
Python中的抽象类通过abc
模块提供的ABC
类和abstractmethod
装饰器定义。抽象类可以包含抽象方法和普通方法。
抽象方法是在抽象类中定义的方法,只有声明,没有实现。子类继承抽象类后,必须实现抽象方法。使用@abstractmethod
装饰器可以将普通方法标记为抽象方法。
2. 抽象类的定义示例
from abc import ABC, abstractmethod
class AbstractClass(ABC):
@abstractmethod
def abstract_method(self):
pass
def normal_method(self):
print("This is a normal method.")
3. 子类继承抽象类的方法
子类继承抽象类后,必须实现抽象方法。否则,在实例化子类时会抛出TypeError
。
子类需要实现抽象方法的示例:
class ConcreteClass(AbstractClass):
def abstract_method(self):
print("This is the implementation of abstract method in the concrete class.")
子类可以调用抽象类中的普通方法,也可以根据需要重写这些方法。
调用抽象类方法的示例:
concrete_instance = ConcreteClass()
concrete_instance.abstract_method() # 输出: This is the implementation of abstract method in the concrete class.
concrete_instance.normal_method() # 输出: This is a normal method.
4. 概念小结:
- 抽象类是通过
abc
模块中的ABC
类和abstractmethod
装饰器定义的。 - 抽象类包含抽象方法和普通方法。
- 抽象方法在抽象类中只有声明,没有实现,需要子类来实现。
- 子类必须实现抽象类中的所有抽象方法,否则会抛出
TypeError
。 - 子类可以调用抽象类中的普通方法,并根据需要重写这些方法。
二、常见错误
在以下情况下,继承抽象类的子类会报错:
1. 没有实现抽象方法
如果子类没有实现抽象类中定义的所有抽象方法,那么在实例化子类时会报错。
示例代码:
from abc import ABC, abstractmethod
class AbstractClass(ABC):
@abstractmethod
def abstract_method(self):
pass
class ConcreteClass(AbstractClass):
pass
# 实例化子类,会报错
c = ConcreteClass()
2. 子类不能实例化
如果抽象类本身没有实现__init__
方法,那么子类不能实例化。
示例代码:
from abc import ABC, abstractmethod
class AbstractClass(ABC):
pass
class ConcreteClass(AbstractClass):
pass
# 实例化子类,会报错
c = ConcreteClass()
3. 子类继承多个抽象类,且这些抽象类有相同方法名但不同参数
如果子类继承了多个抽象类,而这些抽象类有相同的方法名但参数不同,那么在实例化子类时会报错。
示例代码:
from abc import ABC, abstractmethod
class AbstractClassA(ABC):
@abstractmethod
def abstract_method(self, a):
pass
class AbstractClassB(ABC):
@abstractmethod
def abstract_method(self, b):
pass
class ConcreteClass(AbstractClassA, AbstractClassB):
pass
# 实例化子类,会报错
c = ConcreteClass()
这些示例代码中,在实例化子类时都会报错,因为子类没有满足抽象类的要求。
总结
抽象类是一种特殊类型的类,不能被实例化,而是被用作其他类的基类。抽象类的主要目的是为子类提供一个接口,子类必须实现该接口中定义的方法。
以下是对Python抽象类的完整总结:
1. 抽象类是通过abc
模块中的ABC
类和abstractmethod
装饰器来定义的
在定义抽象类时,需要将ABC
作为其基类,并使用abstractmethod
装饰器来标记要求子类必须实现的方法。
例如:
from abc import ABC, abstractmethod
class AbstractClassExample(ABC):
@abstractmethod
def method1(self):
pass
@abstractmethod
def method2(self):
pass
2. 抽象类不能被实例化,只能用作其他类的基类。
例如:
class ConcreteClassExample(AbstractClassExample):
def method1(self):
print("method1 implementation")
def method2(self):
print("method2 implementation")
3. 子类必须实现抽象类中定义的所有抽象方法,否则会引发TypeError
。抽象方法必须在子类中进行实现。
例如:
class InvalidClassExample(AbstractClassExample):
pass
# TypeError: Can't instantiate abstract class InvalidClassExample with abstract methods method1, method2
4. 抽象类可以包含非抽象方法。非抽象方法是可以直接调用的方法,而不需要在子类中进行实现。
例如:
class AbstractClassExample(ABC):
@abstractmethod
def method1(self):
pass
def method2(self):
print("method2 implementation")
class ConcreteClassExample(AbstractClassExample):
def method1(self):
print("method1 implementation")
concrete = ConcreteClassExample()
concrete.method1() # 输出:method1 implementation
concrete.method2() # 输出:method2 implementation
抽象类为我们提供了一种强制约束子类实现特定方法的方式,以及定义类的接口。通过使用抽象类,我们可以确保子类按照指定的方式实现所需的方法,并提供一致的行为。