Python3里的super()和__class__使用介绍


Posted in Python onApril 23, 2015

子类里访问父类的同名属性,而又不想直接引用父类的名字,因为说不定什么时候会去修改它,所以数据还是只保留一份的好。其实呢,还有更好的理由不去直接引用父类的名字,参见 Python's super() considered super! | Deep Thoughts by Raymond Hettinger。

这时候就该 super() 登场啦——

class A:

  def m(self):

    print('A')
class B(A):

  def m(self):

    print('B')

    super().m()
B().m()

当然 Python 2 里 super() 是一定要参数的,所以得这么写:
class B(A):

  def m(self):

    print('B')

    super(B, self).m()

需要提到自己的名字。这个名字也是动态查找的,在这种情况下替换第三方库中的类会出问题。

super() 很好地解决了访问父类中的方法的问题。那么,如果要访问父类的父类(准确地说,是方法解析顺序(MRO)中位于第三的类)的属性呢?

比如,B 类是继承 A 的,它重写了 A 的 m 方法。现在我们需要一个 C 类,它需要 B 类的一些方法,但是不要 B 的 m 方法,而改用 A 的。怎么间接地引用到 A 的 m 方法呢?使用self.__class__肯定是不行的,因为 C 还可能被进一步继承。

从文档中我注意到,super 的实现是通过插入一个名为 __class__ 的名字来实现的(super 会从调用栈里去查找这个 __class__ 名字)。所以,就像文档里暗示的,其实可以直接在定义方法时访问 __class__ 名字,它总是该方法被定义的类。继续我们的单字母类:

class C(B):

  def m(self):

    print('C')

    # see the difference!

    print(__class__.__mro__)

    print(self.__class__.__mro__)

    __class__.__mro__[2].m(self)
class D(C):

  def m(self):

    print('D')

    super().m()
o = D()

o.m()

会得到:
D

C

(<class 't.C'>, <class 't.B'>, <class 't.A'>, <class 'object'>)

(<class 't.D'>, <class 't.C'>, <class 't.B'>, <class 't.A'>, <class 'object'>)

A

不过,PyPy 并不支持这个 __class__ 名字。
Python 相关文章推荐
Python减少循环层次和缩进的技巧分析
Mar 15 Python
Python实现k-means算法
Feb 23 Python
Python用for循环实现九九乘法表
May 31 Python
pandas表连接 索引上的合并方法
Jun 08 Python
python递归函数绘制分形树的方法
Jun 22 Python
python3基于OpenCV实现证件照背景替换
Jul 18 Python
Django处理多用户类型的方法介绍
May 18 Python
500行Python代码打造刷脸考勤系统
Jun 03 Python
用Q-learning算法实现自动走迷宫机器人的方法示例
Jun 03 Python
k-means 聚类算法与Python实现代码
Jun 01 Python
Python requests HTTP验证登录实现流程
Nov 05 Python
python小程序之飘落的银杏
Apr 17 Python
Python实现的飞速中文网小说下载脚本
Apr 23 #Python
Python中使用PyQt把网页转换成PDF操作代码实例
Apr 23 #Python
Python里disconnect UDP套接字的方法
Apr 23 #Python
Python实现的Google IP 可用性检测脚本
Apr 23 #Python
Python3.2中的字符串函数学习总结
Apr 23 #Python
Python与Redis的连接教程
Apr 22 #Python
Python实现的数据结构与算法之快速排序详解
Apr 22 #Python
You might like
模拟flock实现文件锁定
2007/02/14 PHP
php学习笔记 php中面向对象三大特性之一[封装性]的应用
2011/06/13 PHP
php 搜索框提示(自动完成)实例代码
2012/02/05 PHP
PHP读取大文件的多种方法介绍
2016/04/04 PHP
PHP加密技术的简单实现
2016/09/04 PHP
Laravel实现表单提交
2017/05/07 PHP
phpmyadmin下载、安装、配置教程
2017/05/16 PHP
PHP CURL实现模拟登陆并上传文件操作示例
2020/01/02 PHP
用JavaScript页面不刷新时全选择,全删除(GridView)
2009/04/14 Javascript
JavaScript高级程序设计 读书笔记之十 本地对象Date日期
2012/02/27 Javascript
简介JavaScript中fixed()方法的使用
2015/06/08 Javascript
JQuery菜单效果的两个实例讲解(3)
2015/09/17 Javascript
JavaScript操作URL的相关内容集锦
2015/10/29 Javascript
javascript图片预加载完整实例
2015/12/10 Javascript
JavaScript常见事件处理程序实例总结
2019/01/05 Javascript
微信小程序的mpvue框架快速上手指南
2019/05/15 Javascript
浅谈function(函数)中的动态参数
2017/04/30 Python
pandas 实现将重复表格去重,并重新转换为表格的方法
2018/04/18 Python
python获取中文字符串长度的方法
2018/11/14 Python
详解Python传入参数的几种方法
2019/05/16 Python
python爬虫刷访问量 2019 7月
2019/08/01 Python
TensorFlow 输出checkpoint 中的变量名与变量值方式
2020/02/11 Python
使用python的turtle函数绘制一个滑稽表情
2020/02/28 Python
用python对oracle进行简单性能测试
2020/12/05 Python
详解如何用HTML5 Canvas API控制图片的缩放变换
2016/03/22 HTML / CSS
会计毕业生自荐信
2013/11/21 职场文书
教师年度考核自我鉴定
2014/01/19 职场文书
低碳环保标语
2014/06/12 职场文书
机械专业技术员求职信
2014/06/14 职场文书
节水口号标语
2014/06/19 职场文书
2014年店长工作总结
2014/11/17 职场文书
2014年少先队工作总结
2014/12/03 职场文书
员工手册董事长致辞
2015/07/29 职场文书
left join、inner join、right join的区别
2021/04/05 MySQL
postgresql 删除重复数据案例详解
2021/08/02 PostgreSQL
windows11怎么查看wifi密码? win11查看wifi密码的技巧
2021/11/21 数码科技