我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Python实现抽象基类的3三种方法

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Python实现抽象基类的3三种方法

Python的抽象基类类似于Java、C++等面向对象语言中的接口的概念。抽象基类提供了一种要求子类实现指定协议的方式,如果一个抽象基类要求实现指定的方法,而子类没有实现的话,当试图创建子类或者执行子类代码时会抛出异常。这里简单介绍一下Python实现抽象基类的三种方法。


方法一:使用NotImplementedError

见下面的测试代码,只有子类实现了run方法才能运行run。

>>> class Task():
    def __init__(self, x, y):
        self.x = x
        self.y = y

>>> class Task():
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def run(self):
        raise NotImplementedError('Please define "a run method"')

>>> t = Task(1, 2)
>>> t.run()
Traceback (most recent call last):
  File "<pyshell#12>", line 1, in <module>
    t.run()
  File "<pyshell#10>", line 6, in run
    raise NotImplementedError('Please define "a run method"')
NotImplementedError: Please define "a run method"
>>>
>>> class SubTask(Task):
    def __init__(self, x, y):
        super().__init__(x, y)

    def run(self):
        print('Task(x=%s, y=%s)' % (self.x, self.y))

>>> st = SubTask(1, 3)
>>> st.run()
Task(x=1, y=3)
>>> 


方法二:使用元类

class TaskMeta(type):
    def __new__(cls, name, bases, attrs):

        new_class = super(TaskMeta, cls).__new__(cls, name, bases, attrs)

        if attrs.pop('abstract', False):
            return new_class

        if not hasattr(new_class, 'run') or not callable(new_class.run):
            raise TypeError('Please define "a run method"')

        return new_class


class Task(metaclass=TaskMeta):
    abstract = True

    def __init__(self, x, y):
        self.x = x
        self.y = y


class SubTask(Task):
    def __init__(self, x, y):
        super().__init__(x, y)

    def run(self):
        print('Task(x=%s, y=%s)' % (self.x, self.y))

测试代码一:

>>> t = Task(1, 3)
>>> t.run()
Traceback (most recent call last):
  File "E:/Code/python3/loggingTest/task.py", line 32, in <module>
    t.run()
AttributeError: 'Task' object has no attribute 'run'
>>> st = SubTask(1, 3)
>>> st.run()
Task(x=1, y=3)


这个示例类似于方法一,但有一些细微的区别。第一个区别就是Task类本身仍然能被实例化,但是不能运行run方法,否则会抛出AttributeError错误。更为重要的区别在于子类。当子类被创建时元类会运行__new__方法,解释器讲不再允许创建没有run方法的子类。

>>> class SubTask(Task):
...    pass
...
Traceback (most recent call last):
  File "E:/Code/python3/loggingTest/task.py", line 31, in <module>
    class SubTask(Task):
  File "E:/Code/python3/loggingTest/task.py", line 10, in __new__
    raise TypeError('Please define "a run method"')
TypeError: Please define "a run method"


方法三:使用@abstractmethod

  abc模块提供了一个使用某个抽象基类声明协议的机制,并且子类一定要提供了一个符合该协议的实现。

import abc


class Task(metaclass = abc.ABCMeta):
    def __init__(self, x, y):
        self.x = x
        self.y = y

    @abc.abstractmethod
    def run(self):
        pass


class SubTask(Task):
    def __init(self, x, y):
        super().__init__(x, y)

    def run(self):
        print('Task(x=%s, y=%s)' % (self.x, self.y))

class OtherSubTask(Task):
    def __init(self, x, y):
        super().__init__(x, y)

和方法一、方法二的示例类似,但略有不同。第一,Task类本身不能被实例化。

>>> t = Task(1, 3)
Traceback (most recent call last):
  File "E:/Code/python3/loggingTest/test.py", line 23, in <module>
    t = Task(1, 3)
TypeError: Can't instantiate abstract class Task with abstract methods run


这与方法一不同,方法一允许基类Task被实例化。

对于不能正确重写run方法的子类,在错误的情况下它与之前的两个方法的差别也是不同的。方法一中,使用NotImplementedError,最终在run方法被调用时引发NotImplementedError错误。在方法二中,使用了自定义的TaskMeta元类, 当这个抽象类被创建时引发TypeError错误。

当没有实现run方法的子类实例化时会报错,给出的错误信息与实例化Task类时给出的一样,逻辑上完全符合预期。

>>> ot = OtherSubTask(1, 3)
Traceback (most recent call last):
  File "E:/Code/python3/loggingTest/test.py", line 27, in <module>
    ot = OtherSubTask(1, 3)
TypeError: Can't instantiate abstract class OtherSubTask with abstract methods run
但是,当你定义了一个重新了run方法的子类时,那么子类就能够被实例化,就能正常工作。

>>> st = SubTask(1, 3)
>>> st.run()
Task(x=1, y=3)



免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Python实现抽象基类的3三种方法

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Python实现抽象基类的3三种方法

Python的抽象基类类似于Java、C++等面向对象语言中的接口的概念。抽象基类提供了一种要求子类实现指定协议的方式,如果一个抽象基类要求实现指定的方法,而子类没有实现的话,当试图创建子类或者执行子类代码时会抛出异常。这里简单介绍一下Py
2023-01-31

python抽象类的使用方法

这篇文章主要介绍了python抽象类的使用方法,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一、问题描述主要使用场景是这样的比如京东上买东西,买完东西后需要支付,京东可以使用
2023-06-08

python 三元条件判断的3种实现方法

python 三元条件判断的3种实现方法C语言中有三元条件表达式,如 a>b?a:b,Python中没有三目运算符(?:),但Python有它自己的方式来实现类似的功能。这里介绍3种方法:1》true_part if condition e
2023-01-31

函数重写与抽象方法:理解子类实现父类抽象方法的必要性

函数重写允许子类重新定义父类方法,而抽象方法强制子类实现父类的未实现方法。子类实现父类抽象方法至关重要,因为它:提高代码的灵活性和可扩展性;减少代码冗余并促进重用;增强可测试性,允许轻松验证子类是否正确实现了父类接口。函数重写与抽象方法:理
函数重写与抽象方法:理解子类实现父类抽象方法的必要性
2024-05-03

java中抽象类、抽象方法、接口与实现接口实例详解

前言对于java中的抽象类,抽象方法,接口,实现接口等具体的概念就不在这里详细的说明了,网上书本都有很多解释,主要是我懒,下面通过一个例子来说明其中的精髓要点,能不能练成绝世武功,踏上封王之路,就看自己的的啦(不要误会,我指的只是我自己啦啦
2023-05-30

Python实现8种常用抽样方法

目录概率抽样技术1.随机抽样(Random Sampling)2.分层抽样(Stratified Sampling)3.聚类抽样(Cluster Sampling)4.系统抽样(Systematic Sampling)5.多级采样(Mult
2022-06-02

Android中传递对象的三种方法的实现

Android中,Activity和Fragment之间传递对象,可以通过将对象序列化并存入Bundle或者Intent中进行传递,也可以将对象转化为JSON字符串,进行传递。 序列化对象可以使用Java的Serializable的接口、P
2022-06-06

python中怎么实现抽样分类方法

这期内容当中小编将会给大家带来有关python中怎么实现抽样分类方法,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。11.1 算法抽查在实践之前你并不知道哪种算法对你的的数据效果最好。 你需要尝试用不同的算
2023-06-19

Java中多态和抽象类的实现方式

这篇文章主要讲解了“Java中多态和抽象类的实现方式”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java中多态和抽象类的实现方式”吧!  多态  1.要实现多态,那么必须存在父子关系(继承
2023-06-02

python实现下载文件的三种方法

Python开发中时长遇到要下载文件的情况,最常用的方法就是通过Http利用urllib或者urllib2模块。当然你也可以利用ftplib从ftp站点下载文件。此外Python还提供了另外一种方法requests。下面来看看三种方法是如何
2022-06-04

在Python中定义和使用抽象类的方法

像java一样python也可以定义一个抽象类。 在讲抽象类之前,先说下抽象方法的实现。 抽象方法是基类中定义的方法,但却没有任何实现。在java中,可以把方法申明成一个接口。而在python中实现一个抽象方法的简单的方法是:class S
2022-06-04

Vue3实现组件级基类的多种方法

vue3提供了mixins和extends,但是尝试之后发现这两种方法只支持纯OptionAPI,设置的data会被识别,但是设置的setup里return的reactive,完全无效,setup也没有被执行,这篇文章主要介绍了Vue3实现组件级基类的几种方法,需要的朋友可以参考下
2023-05-18

用python实现零钱找零的三种方法

1.递归(recursion)def coins_changeREC(coin_values, change): """ 递归实现零钱找零 """ min_count = change # base case
2023-01-31

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录