Python 简明教程

Python - Abstract Base Classes

在 Python 中, Abstract Base Class (ABC) 是一个不能直接实例化的类,旨在被子类化。ABC 通过提供所有子类都必须实现的通用接口,充当其他类别的蓝图。

它们是 object-oriented programming in Python 中的基本组成部分,它使开发人员能够为一组相关类定义和实施一致的 API。

Purpose of Abstract Base Classes

以下是 Abstract Base Classes of Python 的用途和功能的深入分析 −

Defining a Standard Interface

Abstract Base Class (ABC) 允许我们为其他类定义一个蓝图。该蓝图确保从 Abstract Base Class (ABC) 派生的任何类都通过提供一致的接口来实现某些方法。

以下是定义 Python 中抽象基类的标准接口的示例代码 −

from abc import ABC, abstractmethod

class Shape(ABC):
   @abstractmethod
   def area(self):
      pass

   @abstractmethod
   def perimeter(self):
      pass

Enforcing Implementation

当类从 Abstract Base Class (ABC) 继承时,它必须实现所有 abstract methods 。如果不实现,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

Providing a Template for Future Development

Abstract Base Class (ABC) 在多个开发人员可能处理代码库中不同部分的大型项目中很有用。它们为开发人员提供了一个明确的模板,以确保一致性和减少错误。

Facilitating Polymorphism

Abstract Base Class (ABC) 通过支持与来自不同类的对象进行操作的代码的开发,只要它们符合特定接口,就能使多态性成为可能。此能力简化了代码的扩展和维护。

以下是 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)

Note: 要执行上述示例代码,有必要定义标准接口和强制实现。

Components of Abstract Base Classes

Python 中的 Abstract Base Classes (ABCs) 包含几个关键组件,使它们能够为子类定义和强制实现接口。

这些组件包括 ABC 类、抽象方法装饰器以及其他一些用于创建和管理抽象基类的组件。以下是抽象基类的主要组成部分 −

  1. ABC Class: 这个类来自 Python 的 Abstract Base Classes (ABCs) 模块,用作创建抽象基类的基础。从 ABC 派生的任何类都被认为是抽象基类。

  2. 'abstractmethod' Decorator: abc 模块中的这个装饰器用于将方法声明为抽象方法。这些方法在 ABC 中没有实现,并且必须在派生类中被覆盖。

  3. 'ABCMeta' Metaclass: 这是 ABC 使用的元类。它负责跟踪哪些方法是抽象的,并确保如果未实现任何抽象方法,则无法创建抽象基类的实例。

  4. Concrete Methods in ABCs: 抽象基类还可以定义提供默认实现的具体方法。这些方法可以被子类使用或覆盖。

  5. Instantiation Restrictions: ABC 的一个关键特性是,如果它们有任何抽象方法,则无法直接实例化它们。尝试实例化具有未实现抽象方法的 ABC 会引发一个“TypeError”。

  6. Subclass Verification: Abstract Base Classes (ABCs) 可以使用 issubclass 函数验证给定类是否为子类,并可以使用 isinstance 函数检查实例。

Example of Abstract Base Classes in Python

以下示例显示了 ABC 如何强制方法实现、支持 polymorphism 以及为相关类提供清晰而一致的接口 −

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)

Output

执行上述代码,我们将得到以下输出 −

I am a shape.
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