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编写的微博应用
Oct 17 Python
详解MySQL数据类型int(M)中M的含义
Nov 20 Python
PyQt5实现下载进度条效果
Apr 19 Python
kafka-python批量发送数据的实例
Dec 27 Python
python绘制评估优化算法性能的测试函数
Jun 25 Python
python命令行参数用法实例分析
Jun 25 Python
pycharm编写spark程序,导入pyspark包的3中实现方法
Aug 02 Python
Python完全识别验证码自动登录实例详解
Nov 24 Python
python之列表推导式的用法
Nov 29 Python
pytorch之Resize()函数具体使用详解
Feb 27 Python
15款Python编辑器的优缺点,别再问我“选什么编辑器”啦
Oct 19 Python
在 Golang 中实现 Cache::remember 方法详解
Mar 30 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
缓存技术详谈―php
2006/12/14 PHP
深入理解PHP几个算法:PHP冒泡、PHP二分法、PHP求素数、PHP乘法表
2013/06/06 PHP
php多文件上传实现代码
2014/02/20 PHP
PHP中创建和验证哈希的简单方法实探
2015/07/06 PHP
php关闭warning问题的解决方法
2016/05/17 PHP
MooTools 1.2介绍
2009/09/14 Javascript
JavaScript 语言基础知识点总结(思维导图)
2013/11/10 Javascript
JavaScript中switch判断容易犯错的一个细节
2014/08/27 Javascript
2014年50个程序员最适用的免费JQuery插件
2014/12/15 Javascript
原生js获取iframe中dom元素--父子页面相互获取对方dom元素的方法
2016/08/05 Javascript
关于微信jssdk实现多图片上传的一点心得分享
2016/12/13 Javascript
jquery实现静态搜索功能(可输入搜索文字)
2017/03/28 jQuery
JS创建Tag标签的方法详解
2017/06/09 Javascript
vue动态循环出的多个select出现过的变为disabled(实例代码)
2019/11/10 Javascript
VUE页面中通过双击实现复制表格中内容的示例代码
2020/06/11 Javascript
JSON获取属性值方法代码实例
2020/06/30 Javascript
[01:07:19]2018DOTA2亚洲邀请赛 4.5 淘汰赛 Mineski vs VG 第一场
2018/04/06 DOTA
[41:56]Spirit vs Liquid Supermajor小组赛A组 BO3 第一场 6.2
2018/06/03 DOTA
Python3实现连接SQLite数据库的方法
2014/08/23 Python
Python的Flask框架中实现简单的登录功能的教程
2015/04/20 Python
利用Python+Java调用Shell脚本时的死锁陷阱详解
2018/01/24 Python
Python单元测试简单示例
2018/07/03 Python
Python OpenCV处理图像之滤镜和图像运算
2018/07/10 Python
python多线程分块读取文件
2019/08/29 Python
Python Selenium参数配置方法解析
2020/01/19 Python
Python 开发工具PyCharm安装教程图文详解(新手必看)
2020/02/28 Python
用Python进行websocket接口测试
2020/10/16 Python
Molly Bracken法国电子商店:法国女性时尚品牌
2019/07/24 全球购物
一些Unix笔试题和面试题
2012/09/25 面试题
JSP&Servlet技术面试题
2015/05/21 面试题
优秀老师事迹材料
2014/02/05 职场文书
优秀求职信
2014/05/29 职场文书
委托书怎样写
2014/08/30 职场文书
python文件名批量重命名脚本实例代码
2021/04/22 Python
秀!学妹看见都惊呆的Python小招数!【详细语言特性使用技巧】
2021/04/27 Python
详解Js模块化的作用原理和方案
2021/04/29 Javascript