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使用urllib模块开发的多线程豆瓣小站mp3下载器
Jan 16 Python
用Python编写生成树状结构的文件目录的脚本的教程
May 04 Python
详解python之多进程和进程池(Processing库)
Jun 09 Python
基于pandas数据样本行列选取的方法
Apr 20 Python
详解Python中的四种队列
May 21 Python
Python基于多线程操作数据库相关问题分析
Jul 11 Python
浅析Python函数式编程
Oct 06 Python
Python之Class&amp;Object用法详解
Dec 25 Python
Python常用模块sys,os,time,random功能与用法实例分析
Jan 07 Python
Python实现子类调用父类的初始化实例
Mar 12 Python
python爬虫爬取淘宝商品比价(附淘宝反爬虫机制解决小办法)
Dec 03 Python
在NumPy中深拷贝和浅拷贝相关操作的定义和背后的原理
Apr 14 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与MySQL开发中页面出现乱码的一种解决方法
2007/07/29 PHP
Laravel5中Cookie的使用详解
2017/05/03 PHP
PHP小程序支付功能完整版【基于thinkPHP】
2019/03/26 PHP
PHP程序守护进程化实现方法详解
2020/07/16 PHP
海量经典的jQuery插件集合
2010/01/12 Javascript
js最简单的拖拽效果实现代码
2010/09/24 Javascript
javascript开发技术大全-第1章javascript概述
2011/07/03 Javascript
JavaScript自定义日期格式化函数详细解析
2014/01/14 Javascript
jQuery制作简洁的图片轮播效果
2015/04/03 Javascript
seajs模块之间依赖的加载以及模块的执行
2016/10/21 Javascript
分析javascript原型及原型链
2018/03/18 Javascript
koa socket即时通讯的示例代码
2018/09/07 Javascript
在vue中使用express-mock搭建mock服务的方法
2018/11/07 Javascript
JS实现的贪吃蛇游戏完整实例
2019/01/18 Javascript
了解重排与重绘
2019/05/29 Javascript
基于JS正则表达式实现模板数据动态渲染(实现思路详解)
2020/03/07 Javascript
js删除指定位置超链接中含有百度与360的标题
2021/01/06 Javascript
python去除文件中空格、Tab及回车的方法
2016/04/12 Python
python解决汉字编码问题:Unicode Decode Error
2017/01/19 Python
python3监控CentOS磁盘空间脚本
2018/06/21 Python
numpy库与pandas库axis=0,axis= 1轴的用法详解
2019/05/27 Python
Python计算两个矩形重合面积代码实例
2019/09/16 Python
python super的使用方法及实例详解
2019/09/25 Python
python单例设计模式实现解析
2020/01/07 Python
Jupyter notebook如何实现指定浏览器打开
2020/05/13 Python
python中PyQuery库用法分享
2021/01/15 Python
python正则表达式re.match()匹配多个字符方法的实现
2021/01/27 Python
Python如何实现Paramiko的二次封装
2021/01/30 Python
在html5的Canvas上绘制椭圆的几种方法总结
2013/01/07 HTML / CSS
Clarria化妆品官方网站:购买天然和有机化妆品系列
2018/04/08 全球购物
世界上最大的隐形眼镜商店:1-800 Contacts
2018/11/03 全球购物
测绘工程本科生求职信
2013/10/10 职场文书
土建资料员岗位职责
2014/01/04 职场文书
百日安全生产活动总结
2014/07/05 职场文书
资产运营委托书范本
2014/10/16 职场文书
经典励志格言:每日一句,让你每天充满能量
2019/08/16 职场文书