Python 中的抽象基类 (ABC) 是一个不能直接实例化的类,旨在被子类化。ABC 通过提供所有子类都必须实现的通用接口来充当其他类的蓝图。
它们是 Python 中面向对象编程的基本部分,使开发人员能够为一组相关类定义和实施一致的 API。
抽象基类的用途
以下是对 Python 抽象基类的用途和功能的深入了解 -
定义标准接口
抽象基类 (ABC) 允许我们为其他类定义蓝图。此蓝图通过提供一致的接口来确保从抽象基类 (ABC) 派生的任何类都实现某些方法。
以下是在 Python 中定义抽象基类的标准接口的示例代码 -
from abc import ABC, abstractmethod
class Shape(ABC):
@abstractmethod
def area(self):
pass
@abstractmethod
def perimeter(self):
pass
强制实施
当类从抽象基类 (ABC) 继承时,它必须实现所有抽象方法。如果没有,则 Python 将引发 TypeError。以下是在 Python 中强制实现抽象基类的示例 -
class Rectangle(Shape):
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
def perimeter(self):
return 2 * (self.width + self.height)
# This will work
rect = Rectangle(5, 10)
# This will raise TypeError
class IncompleteShape(Shape):
pass
为未来发展提供模板
抽象基类 (ABC) 在多个开发人员可能处理代码库的不同部分的大型项目中非常有用。它们为开发人员提供了一个明确的模板,以确保一致性并减少错误。
促进多态性
抽象基类 (ABC) 通过支持开发代码来使多态性成为可能,这些代码可以处理来自不同类的对象,只要它们符合特定的接口即可。此功能简化了代码的扩展和维护。
下面是 Facilitating Polymorphism in Abstract Base Class of Python 的示例 -
def print_shape_info(shape: Shape):
print(f"Area: {shape.area()}")
print(f"Perimeter: {shape.perimeter()}")
square = Rectangle(4, 4)
print_shape_info(square)
注意:要执行上述示例代码,必须定义标准接口和 Enforcing Implementation。
抽象基类的组件
Python 中的抽象基类 (ABC) 由几个关键组件组成,这些组件使它们能够定义和强制执行子类的接口。
这些组件包括 ABC 类、abstractmethod 装饰器和其他几个有助于创建和管理抽象基类的组件。以下是抽象基类的关键组件 -
- ABC 类:Python 的抽象基类 (ABC) 模块中的这个类用作创建抽象基类的基础。从 ABC 派生的任何类都被视为抽象基类。
- 'abstractmethod' 装饰器:abc 模块中的这个装饰器用于将方法声明为 abstract。这些方法在 ABC 中没有实现,必须在派生类中重写。
- 'ABCMeta' 元类:这是 ABC 使用的元类。它负责跟踪哪些方法是抽象的,并确保如果未实现任何抽象方法,则无法创建抽象基类的实例。
- ABC 中的具体方法:抽象基类还可以定义提供默认实现的具体方法。这些方法可以被子类使用或覆盖。
- 实例化限制:ABC 的一个关键特性是,如果它们有任何抽象方法,则不能直接实例化它们。尝试使用未实现的抽象方法实例化 ABC 将引发 'TypeError'。
- 子类验证:抽象基类 (ABC) 可以使用 issubclass 函数验证给定类是否为子类,并可以使用 isinstance 函数检查实例。
Python 中的抽象基类示例
以下示例显示了 ABC 如何强制执行方法实现、支持多态性并为相关类提供清晰一致的接口 -
from abc import ABC, abstractmethod
class Shape(ABC):
@abstractmethod
def area(self):
pass
@abstractmethod
def perimeter(self):
pass
def description(self):
return "I am a shape."
class Rectangle(Shape):
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
def perimeter(self):
return 2 * (self.width + self.height)
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
import math
return math.pi * self.radius ** 2
def perimeter(self):
import math
return 2 * math.pi * self.radius
def print_shape_info(shape):
print(shape.description())
print(f"Area: {shape.area()}")
print(f"Perimeter: {shape.perimeter()}")
shapes = [Rectangle(5, 10), Circle(7)]
for shape in shapes:
print_shape_info(shape)
print("-" * 20)
class IncompleteShape(Shape):
pass
try:
incomplete_shape = IncompleteShape()
except TypeError as e:
print(e)
输出
在执行上述代码时,我们将得到以下输出 -
Area: 50
Perimeter: 30
--------------------
I am a shape.
Area: 153.93804002589985
Perimeter: 43.982297150257104
--------------------
Can't instantiate abstract class IncompleteShape with abstract methods area, perimeter