禁止 Python 子类覆盖父类方法

news/2024/7/3 4:21:35
当实现我们自己的父类Animal的时候,由于meta.has_base为 False,所以不会触发检查逻辑。但当我们基于Animal实现Dog子类的时候,由于meta.has_base是True,所以进入检查逻辑。Dog的所有方法名都在attrs参数里面。循环检查每一个方法名是否在禁止的列表中,如果在,就抛出异常。如果不在,就继续后面的创建过程。

禁止 Python 子类覆盖父类方法禁止 Python 子类覆盖父类方法

当子类试图覆盖父类的时候,可以通过类型标注来发出警告。今天,我们来讲讲如何直接禁止覆盖。

Python 原生是没有提供禁止子类覆盖父类的方法的功能,因此我们需要自己来实现。

先来看一下实现效果:

禁止 Python 子类覆盖父类方法禁止 Python 子类覆盖父类方法

在这段代码里面,我们禁止子类覆盖父类的dead()和eat()方法,但不禁止move方法。所以,当我们在子类Dog里面尝试覆盖父类中的dead()时,程序就报错了。具体要覆盖哪些方法,可以在定义类的时候指定,传入的参数metaclass=protect('方法1', '方法2', '方法3', ...)就可以了。

那么这个protect函数是个什么东西呢?我们来看看它的代码:

def protect(*protected): """Returns a metaclass that protects all attributes given as strings""" class Protect(type): has_base = False def __new__(meta, name, bases, attrs): if meta.has_base: for attribute in attrs: if attribute in protected: raise AttributeError('Overriding of attribute "%s" not allowed.'%attribute) meta.has_base = True klass = super().__new__(meta, name, bases, attrs) return klass return Protect 

这里,用到了 Python 的元类。如果大家对元类有兴趣,可以看9.13 使用元类控制实例的创建 — python3-cookbook 3.0.0 文档[1]。简单的来说,元类用来定义类的创建行为。它一般的格式为:

class 类名(metaclass=另一个类): ... 

而大家看我们用来禁止重试的这个函数protect,它返回的就是一个Protect类。这个类继承于type对象。

Protect类有一个__new__方法,这个方法会在使用了元类的所有子类的__init__之前被调用。在__new__里面,我们拿到了子类要定义的方法,并且检查他们是不是在我们传给protect的列表里面。如果在,说明这个方法不能被覆盖。

当实现我们自己的父类Animal的时候,由于meta.has_base为 False,所以不会触发检查逻辑。但当我们基于Animal实现Dog子类的时候,由于meta.has_base是True,所以进入检查逻辑。Dog的所有方法名都在attrs参数里面。循环检查每一个方法名是否在禁止的列表中,如果在,就抛出异常。如果不在,就继续后面的创建过程。

元类在理解上可能比较困难。如果大家无法理解上面这一段也没有关系,直接用就是了。


http://lihuaxi.xjx100.cn/news/283438.html

相关文章

人生苦短,初学者应该如何更快的学好Python?

时光在不经意中流逝,转眼间我已经毕业十余载。一边是时间的年轮不会停止等待,一边是科技的发展已经不能单单用惊叹来记载。很幸运的是,计算机编程语言在科技发展浪潮中的地位不可代替。我们作为一名程序开发者,也伴随着科技的发展…

避免资源死锁:识别已打开的事务

死锁往往由于以下原因引起:1、程序错误,比如一个事务需要操作两个表,由于程序错误在有时是先操作a表后操作b表,有时是先操作b表后操作a表,就有机会互相等待而造成死锁。2、事务太大,大事务操作的表多&#…

你绝对想不到,双非本科的我是如何发表 3 篇深度学习 EI 论文的?

PS:本文中的我不是阿广,是原作者。我是sh,黑龙江某双非大学计算机专业本科在读,目前是正在准备考研中,研究生专业也打算申计算机。因为计算机专业竞争比较激烈,加上我自己本科背景不是很好,所以…

linux 大量的TIME_WAIT解决办法

统计在一台前端机上高峰时间TCP连接的情况,统计命令:netstat -n | awk /^tcp/ {S[$NF]} END {for(a in S) print a, S[a]} 结果: 除了ESTABLISHED,可以看到连接数比较多的几个状态是:FIN_WAIT1, TIME_WAIT, CLOSE_WAI…

win7压缩包安装mysql_win7怎么安装mysql5.7.13压缩文件图解

匿名用户1级2016-07-04 回答1、运行mysql安装文件。 2、 按Next,然后选择安装方式,有"Typical(默认)"、"Complete(完全)"、"Custom(用户自定义)",选择第二个选项"Custom",下一步,MySQL S…

这三个Python小技巧你要知道

我们知道,字典的本质是哈希表,本身是无法排序的,但 Python 3.6 之后,字典是可以按照插入的顺序进行遍历的,这就是有序字典,其中的原理,可以阅读为什么 Python3.6 之后字典是有序的。今天分享 3 …

百度宣布:搜索业务总裁向海龙离职,另回购10亿美元股份

整理 | 一一出品 | AI科技大本营(ID:rgznai100)5 月 17 日,百度公布 2019 年第一季度未经审计的财务报告。本季度百度营收 241 亿元(约合35.9亿美元),同比增长15%,不计入此前宣布的资产剥离交易…

重上热搜!北师大教授:给非洲留学生1年10万奖学金真的不算多!

来源 | 考博圈编辑 | 学术君近日,北师大教授“给非洲留学生一年十万左右奖学金并不多”莫名其妙又上了知乎热搜?知乎一时间引起了网友的鸣不平!事情的来龙去脉是这样的:某关于《外国人永久居留管理条例》的“征求意见稿”成热议&a…