python中的抽象基类ABC

本文介绍了Python中的抽象基类(ABC)概念及其使用方法。通过示例对比了直接继承抽象基类与注册虚拟子类的区别,并展示了如何使用abc模块定义抽象方法确保子类必须实现这些方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

python中的抽象基类(ABC,Abstract Base Class)相当于是Java中的接口,抽象基类就是定义各种方法而可以不做具体实现的类,当然也可以实现,只不过子类如果想调用抽象基类中定义的方法需要使用super()


抽象基类的使用:
1、直接继承
直接继承抽象基类的子类就没有这么灵活,抽象基类中可以声明”抽象方法“和“抽象属性”,只有完全覆写(实现)了抽象基类中的“抽象”内容后,才能被实例化,而虚拟子类则不受此影响。
2、虚拟子类
将其他的类”注册“到抽象基类下当虚拟子类(调用register方法),虚拟子类的好处是你实现的第三方子类不需要直接继承自基类,可以实现抽象基类中的部分API接口,也可以根本不实现,但是issubclass(), issubinstance()进行判断时仍然返回真值。



python中并没有提供抽象类与抽象方法,但是提供了内置模块abc(abstract base class)来模拟实现抽象类。

例:
定义一个抽象基类的简单方法: 首先在Dog,Duck都继承自Animal。 在Animal中定义了eat和run两个方法,任何从Animal中继承的子类都必须实现eat和voice方法。否则调用的时候会报错

例:

class Animal(object):
    def eat(self):
        raise NotImplementedError

    def run(self):
        raise NotImplementedError

class Dog(Animal):
    def eat(self):
        print("dog is eating")

    def run(self):
        print("dog is running")


class Duck(Animal):
    def eat(self):
        print("duck is eating")

    # def run(self):
    #     print("duck is running")


dog = Dog()
duck = Duck()
dog.eat()
dog.run()
duck.eat()
duck.run()

# 结果
dog is eating
dog is running
duck is eating
Traceback (most recent call last):
  File "D:/py3.7Project/sample/chapter01/all_is_object.py", line 83, in <module>
    duck.run()
  File "D:/py3.7Project/sample/chapter01/all_is_object.py", line 59, in run
    raise NotImplementedError
NotImplementedError

以上的大家开始学习实现的方式,这种实现当调用方法的时候才会报错,在实际情况中存在不合理之处,当duck实例化成功后就应该具有eat、run行为,鸭子生下来就应该会吃会跑,所以我们需要的是如果没有实现eat或run方法,实例化就应该是失败的

修改代码如下:

import abc
class Animal(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def eat(self):
        pass

    @abc.abstractmethod
    def run(self):
        pass

class Dog(Animal):
    def eat(self):
        print("dog is eating")

    def run(self):
        print("dog is running")


class Duck(Animal):
    def eat(self):
        print("duck is eating")

    # def run(self):
    #     print("duck is running")


dog = Dog()
duck = Duck()
dog.eat()
dog.run()
duck.eat()


#结果 
Traceback (most recent call last):
  File "D:/py3.7Project/sample/chapter01/all_is_object.py", line 80, in <module>
    duck = Duck()
TypeError: Can't instantiate abstract class Duck with abstract methods run

结果显示无法实例化,提示没有实现eat方法。这样就达到了我们的目的即没有实现抽象基类的所有方法就无法实例化

### Python 抽象基类 (ABC) 的概念 抽象基类是在面向对象编程中定义接口的一种方式。在 Python 中,`abc` 模块提供了实现抽象基类的支持[^1]。 #### 定义抽象基类 要创建一个抽象基类,需导入 `abc` 模块并使用 `ABC` 类作为基类之一,在其中声明至少一个带有装饰器 `@abstractmethod` 的方法。这使得该类无法被实例化除非其所有抽象方法都被重写[^2]。 ```python from abc import ABC, abstractmethod class MyAbstractClass(ABC): @abstractmethod def my_abstract_method(self): """这是一个必须由子类实现的方法""" pass ``` #### 继承自抽象基类 当有具体类继承于上述抽象基类时,则它要么实现了所有的抽象方法,要么本身也标记为抽象类。如果未覆盖这些方法而尝试实例化此类会抛出错误。 ```python class ConcreteClass(MyAbstractClass): def my_abstract_method(self): print("Concrete implementation of the method.") obj = ConcreteClass() # 这是可以正常工作的 obj.my_abstract_method() ``` #### 虚拟子类机制 除了传统的继承关系外,还可以利用 `register()` 方法来注册其他类型的对象成为某个特定抽象基类的“虚拟子类”。这种方式并不强制要求实际继承结构上的关联,而是基于协议或约定的形式来进行类型检查和行为确认[^4]。 ```python import collections.abc collections.abc.Sequence.register(tuple) print(isinstance((1, 2), collections.abc.Sequence)) # True ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值