跳至内容
快速入门 abc 模块

快速入门 abc 模块

2025年03月12日·竹子是不秋草
竹子是不秋草

在 Python 中,抽象类(Abstract Base Class, ABC)是一种不能被直接实例化的类,它主要用于定义一套子类必须遵守的接口规范。抽象类通过强制子类实现特定的方法,来保证代码的一致性和可维护性。

比如我们需要定义一个图形类,要求所有的子类(三角形、圆形、矩形等等)都必须实现计算面积和周长的方法。我们可以使用抽象类来实现这一点。

抽象类及抽象方法

现在定义一个抽象类及若干抽象方法(通过@abstractmethod),其子类必须实现这些抽象方法:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
from abc import ABC, abstractmethod

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

    @abstractmethod
    def perimeter(self) -> float:
        pass
        
class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius
        
    def area(self) -> float:
        return 3.14 * self.radius ** 2
        
    def perimeter(self) -> float:
        return 2 * 3.14 * self.radius
    
class Rectangle(Shape):
    def __init__(self, width, height):
        self.width = width
        self.height = height
        
    def area(self) -> float:
        return self.width * self.height
        
        
# 创建 Circle 和 Rectangle 对象
circle = Circle(5)
print("Circle Area:", circle.area())            # 输出: Circle Area: 78.5
print("Circle Perimeter:", circle.perimeter())  # 输出: Circle Perimeter: 31.400000000000002


# 尝试实例化 Shape 类会引发错误
try:
    shape = Shape()
except TypeError as e:
    print("Error:", e)  # 输出: Error: Can't instantiate abstract class Shape without an implementation for abstract methods 'area', 'perimeter'
    
# Rectangle 类未实现 perimeter 方法,尝试实例化 Rectangle 类会引发错误
try:
    rectangle = Rectangle(4, 6)
except TypeError as e:
    print("Error:", e)  # 输出: Error: Can't instantiate abstract class Rectangle with an implementation for abstract method 'perimeter'

上面的代码创建一个抽象类 Shape,以及如何实现它的子类 CircleRectangle。注意,Rectangle 类没有实现 perimeter 方法,因此尝试实例化它会引发错误。

抽象属性

还可以定义抽象抽象属性(通过@abstractmethod@property):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
from abc import ABC, abstractmethod
class Person(ABC):
    @property   # 注意:@property 只定义属性的 gette
    @abstractmethod
    def age(self) -> int:
        pass
        
    @property
    @abstractmethod
    def name(self) -> str:
        pass
    
    @property
    @abstractmethod
    def gender(self) -> str:
        pass

class Male(Person):

    def __init__(self, age: int, name: str):
        self._age = age
        self._name = name
        
    @property
    def age(self) -> int:
        return self._age
    
    @property
    def name(self) -> str:
        return self._name
        
    @property
    def gender(self) -> str:
        return "Male"
        

class Female(Person):

    def __init__(self, age: int, name: str):
        self._age = age
        self._name = name
        
    @property
    def age(self) -> int:
        return self._age
    
    @property
    def name(self) -> str:
        return self._name
        

# 获取实例属性
car = Male(age=30, name="John")
print(car.age)  # 输出: 30
print(car.name)  # 输出: John
print(car.gender)  # 输出: Male


# Female 类未实现 gender 属性,尝试实例化 Female 类会引发错误
try:
    female = Female(age=25, name="Jane")
except TypeError as e:
    print("Error:", e)  # 输出: Error: Can't instantiate abstract class Female without an implementation for abstract method 'gender'

# 尝试修改只读的抽象类属性会引发 AttributeError
try:
    car.age = 5  
except AttributeError as e:
    print("Error:", e) # 输出: Error: property 'age' of 'Male' object has no setter

上面的代码创建若干只读的抽象属性 agenamegender。任何继承自 Person 的子类都必须实现这些属性,否则会抛出错误。

下一步

本篇主旨是帮助读者快速入门 logging 模块,想要详细掌握需要阅读 abc — 抽象基类

最后更新于