Python强制子类重写父类的两种方法实现

 更新时间:2024年02月23日 11:28:55   作者:软件测试君  
在Python中,有时候我们希望某个类能够被子类继承并重写其中的某些方法,本文主要介绍了Python强制子类重写父类的两种方法实现,具有一定的参考价值,感兴趣的可以了解一下

Python v3.7.0

方案一(推荐)

定义抽象基类,只要把一个方法定义成抽象方法,那解释器就会要求子类必须重写这个方法,要注意的是,如果抽象方法没有被重写,那么子类在实例化时,就会抛出TypeError异常,而不需要等到调用函数。

import abc

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

class Dog(Animal):
    def run(self):
        pass

if __name__ == '__main__':
    dog = Dog()

运行以上代码,会抛出异常:

TypeError: Can't instantiate abstract class Dog with abstract methods speak

只有在Dog子类中,重写speak方法,才可以正常实例化子类。

方案二

指定父类方法抛出NotImplementedError异常

class Animal1():
    def speak(self):
        raise NotImplementedError

class Dog1(Animal1):
    def run(self):
        pass

if __name__ == '__main__':
    dog = Dog1()
    dog.speak()

子类中若没有重写speak方法,也可以正常实例化,但是调用此方法时,就会抛出NotImplementedError异常。

补充

在父类中定义的私有方法,其作用范围仅在当前类,若在子类中重写,实际上并不会起效果,原因:以双下划线前缀开头的属性或方法,Python解释器会重写其名称,以便在类被扩展的时候不容易产生冲突,这被称之为名称修饰(name mangling),如下所示:

class Test:
    def __init__(self):
        self.__foo = True

    def __bar(self):
        return "bar"

t = Test()
print(dir(t))
print(t._Test__foo)
print(t._Test__bar())

输出内容如下,注意列表前两个值,这同时也说明在Python中是没有绝对私有的变量或方法的。

['_Test__bar', '_Test__foo', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
True
bar

在类的继承中,如果在子类中重写了父类方法,但有时也希望能同时实现父类的功能,最常见的场景之一就是父类构造方法中的初始值无法被继承,可以在子类中使用super 函数来调用父类中的方法,特别是多重继承的情况;如下面的例子:

class Animal:
    def __init__(self):
        self.hungry = True

    def eat(self):
        if self.hungry:
            print('No!')
        else:
            print('Yes!')


class Bird(Animal):
    def __init__(self):
        self.song = '~~~'

    def sing(self):
        print(self.song)

bird = Bird()
bird.sing()   # 正常
bird.eat()    # 抛出异常:AttributeError: 'Bird' object has no attribute 'hungry'

解决的方法是在子类的构造函数中,使用super方法调用父类的构造函数,如下:

class Bird(Animal):
    def __init__(self):
        super().__init__()
        self.song = '~~~'

到此这篇关于Python强制子类重写父类的两种方法实现的文章就介绍到这了,更多相关Python强制子类重写父类内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家! 

相关文章

  • Python 加密与解密小结

    Python 加密与解密小结

    这篇文章主要介绍了Python 加密与解密,使用base64或pycrypto模块需要的朋友可以参考下
    2018-12-12
  • 如何基于Python制作有道翻译小工具

    如何基于Python制作有道翻译小工具

    这篇文章主要介绍了如何基于Python制作有道翻译小工具,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-12-12
  • python多线程实现同时执行两个while循环的操作

    python多线程实现同时执行两个while循环的操作

    这篇文章主要介绍了python多线程实现同时执行两个while循环的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-05-05
  • pycharm调试功能如何实现跳到循环的某一步

    pycharm调试功能如何实现跳到循环的某一步

    这篇文章主要介绍了pycharm调试功能如何实现跳到循环的某一步问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • Python读取文件的8种常用方式

    Python读取文件的8种常用方式

    这篇文章主要给大家介绍了关于Python读取文件的8种常用方式,在编程语言中,文件读写是最常见的IO操作,文中通过代码示例介绍的非常详细,需要的朋友可以参考下
    2023-09-09
  • 使用Python和OpenCV进行视觉图像分割的代码示例

    使用Python和OpenCV进行视觉图像分割的代码示例

    在图像处理领域,图像分割是一项基础且关键的技术,它涉及到将图像划分为若干个具有特定属性的区域,本文将通过一个实践项目,展示如何使用Python编程语言,结合OpenCV库,对一张玫瑰花的图片进行图像分割,需要的朋友可以参考下
    2025-01-01
  • Python图像阈值化处理及算法比对实例解析

    Python图像阈值化处理及算法比对实例解析

    这篇文章主要介绍了Python图像阈值化处理及算法比对实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-06-06
  • Python利用递归实现文件的复制方法

    Python利用递归实现文件的复制方法

    今天小编就为大家分享一篇Python利用递归实现文件的复制方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-10-10
  • Python 图像处理之PIL库详解用法

    Python 图像处理之PIL库详解用法

    对于图像识别,大量的工作在于图像的处理,处理效果好,那么才能很好地识别,因此,良好的图像处理是识别的基础。在Python中,有一个优秀的图像处理框架,就是PIL库,本文会介绍PIL库中的各种方法,并列举相关例子
    2021-11-11
  • Python Scrapy库构建基础爬虫

    Python Scrapy库构建基础爬虫

    这篇文章主要为大家介绍了Python Scrapy库构建基础爬虫示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-08-08

最新评论