Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >禁止 Python 子类覆盖父类方法

禁止 Python 子类覆盖父类方法

原创
作者头像
用户9239730
发布于 2021-11-30 04:30:20
发布于 2021-11-30 04:30:20
1.9K00
代码可运行
举报
文章被收录于专栏:运维技术知识运维技术知识
运行总次数:0
代码可运行

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

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

先来看一下实现效果:

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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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]。简单的来说,元类用来定义类的创建行为。它一般的格式为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class 类名(metaclass=另一个类): 
   ... 

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

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

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

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

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
极简Python入门
本文旨在帮助从总体上帮助了解Python的一些基本属性,具体的使用技巧需要通过不断实践积累 一、Python的基本特性 二、Python的类 面向对象编程,是一种程序设计思想。OOP把对象作
智能算法
2018/04/03
1.3K0
极简Python入门
类和对象的创建过程(元类,__new__,__init__,__call__)
一、 type() 1、创建类的两种方式 方式一 class MyClass(object): def func(self,name): print(name) myc = MyClass() print(MyClass, type(MyClass)) print(myc, type(myc)) 我们创建了一个名为MyClass的类,并实例化了这个类,得到其对象myc 上面代码打印的结果为: <class '__main__.MyClass'> <class 'type'>
用户1214487
2018/01/24
1.3K0
10-面向对象2
isinstance()判断的是一个对象是否是该类型本身,或者位于该类型的父继承链上 。
用户3106371
2019/03/11
1.6K0
python-静态方法staticmethod、类方法classmethod、属性方法property
Python的方法主要有3个,即静态方法(staticmethod),类方法(classmethod)和实例方法:
狼啸风云
2019/12/19
2.3K0
python 面向对象技巧 元类
动态语言和静态语言最大的不同,就是函数和类的定义,不是编译时定义的,而是运行时动态创建的。
葫芦
2019/04/17
3260
流畅的 Python 第二版(GPT 重译)(十三)
类元编程是在运行时创建或自定义类的艺术。在 Python 中,类是一等对象,因此可以使用函数在任何时候创建一个新类,而无需使用 class 关键字。类装饰器也是函数,但设计用于检查、更改甚至替换装饰的类为另一个类。最后,元类是类元编程的最高级工具:它们让你创建具有特殊特性的全新类别的类,例如我们已经看到的抽象基类。
ApacheCN_飞龙
2024/03/21
2160
流畅的 Python 第二版(GPT 重译)(十三)
Python面试题之Python面向对象编程汇总
面向对象的设计思想是从自然界中来的,因为在自然界中,类(Class)和实例(Instance)的概念是很自然的。Class是一种抽象概念,比如我们定义的Class——Student,是指学生这个概念,而实例(Instance)则是一个个具体的Student,比如,Bart Simpson和Lisa Simpson是两个具体的Student。
Jetpropelledsnake21
2019/02/15
1.8K0
Python学习笔记(七)·面向对象高级编程
数据封装、继承和多态只是面向对象程序设计中最基础的 3 个概念。在 Python 中,面向对象还有很多高级特性,允许我们写出非常强大的功能。
公爵
2022/09/28
5680
Python学习笔记(七)·面向对象高级编程
Python中使用type、metacl
我们知道动态语言和静态语言最大的不同,就是函数和类的定义,不是编译时定义的,而是运行时动态创建的。
py3study
2020/01/16
4240
python3 metaclass--创
之前学python的时候就看见过metaclass的文章,没看懂,那篇博客后面说到,metaclass是python的黑魔法99% 不会用到。于是果断放弃。
py3study
2020/01/13
4600
一日一技:如何让 Python 提醒你不能覆盖某个父类方法?
在前几天的文章:一日一技:在 Python 里面如何实现一个抽象类中,我们讲到Python 可以实现一个抽象类。抽象类里面有一些抽象方法,在继承这个抽象类的时候,子类必须实现这些抽象方法。
青南
2021/10/19
1K0
一日一技:如何让 Python 提醒你不能覆盖某个父类方法?
Python3.6学习笔记(三)
面向对象编程 Object Oriented Programming 简称 OOP,是一种程序设计思想。OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。
大江小浪
2018/09/19
4030
Python3.6学习笔记(三)
Python 5.5 使用元类
动态语言和静态语言最大的不同,就是函数和类的定义,不是编译时创建的,而是运行时动态创建的。
py3study
2020/01/09
5470
每天一道 python 面试题 - Python中的元类(metaclass) 详细版本
在理解元类之前,您需要掌握Python的类。Python从Smalltalk语言中借用了一个非常特殊的类概念。
公众号---人生代码
2020/05/02
6320
每天一道 python 面试题 - Python中的元类(metaclass) 详细版本
python简明笔记
通过 for 语句我们可以使用 for 循环。Python 里的 for 循环与 C 语言中的不同。这里的 for 循环遍历任何序列(比如列表和字符串)中的每一个元素。下面给出示例:
拾点阳光
2018/05/03
2.3K0
python简明笔记
Django源码中的metaclass使用是如何兼容Python2和Python3的
之前看Django源码时没太注意metaclass是怎么做的2跟3的兼容,直到看见Django2.0dev版中只是用了Python3.x中metaclass的使用方式。
the5fire
2019/03/01
1.1K0
Python中元类的概念
在面向对象编程中,元类是一种特殊的类,用于创建其他类。简单来说,元类是用来定义类的类。在Python中,一切皆对象,包括类本身。因此,我们可以使用元类来定制类的创建过程,控制类的行为。
疯狂的KK
2023/08/05
2450
Python中元类的概念
Python教程第7章 | 元类
在了解元类之前,我们先进一步理解 Python 中的类,在大多数编程语言中,类就是一组用来描述如何生成一个对象的代码段。在 Python 中这一点也是一样的。
仲君Johnny
2024/01/24
1710
Python教程第7章 | 元类
10 . Python之面向对象
类中的方法一般都是通过对象执行的(除去类方法,静态方法外),并且对象执行这些方法都会自动将对象空间传给方法中的第一个参数self
iginkgo18
2020/09/27
4270
10 . Python之面向对象
Python 中的元类
什么是“元类”?按照孔夫子所说的“温故而知新”,先温故,顺着“温故”的操作,会发现新问题。
老齐
2021/11/04
7080
相关推荐
极简Python入门
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验