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结合shell查询google关键词排名的实现代码
Feb 27 Python
Python使用Redis实现作业调度系统(超简单)
Mar 22 Python
在CMD命令行中运行python脚本的方法
May 12 Python
Python PyAutoGUI模块控制鼠标和键盘实现自动化任务详解
Sep 04 Python
python高效过滤出文件夹下指定文件名结尾的文件实例
Oct 21 Python
3分钟学会一个Python小技巧
Nov 23 Python
python 对多个csv文件分别进行处理的方法
Jan 07 Python
python 将大文件切分为多个小文件的实例
Jan 14 Python
python实现动态创建类的方法分析
Jun 25 Python
Python要如何实现列表排序的几种方法
Feb 21 Python
Python处理mysql特殊字符的问题
Mar 02 Python
python 调用Google翻译接口的方法
Dec 09 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
通达OA公共代码 php常用检测函数
2011/12/14 PHP
基于php使用memcache存储session的详解
2013/06/25 PHP
强制PHP命令行脚本单进程运行的方法
2014/04/15 PHP
php实时倒计时功能实现方法详解
2017/02/27 PHP
如何在Web页面上直接打开、编辑、创建Office文档
2007/03/12 Javascript
js控制web打印(局部打印)方法整理
2013/05/29 Javascript
JS 精确统计网站访问量的实例代码
2013/07/05 Javascript
利用jq让你的div居中的好方法分享
2013/11/21 Javascript
JavaScript结合AJAX_stream实现流式显示
2015/01/08 Javascript
js实现按钮控制图片360度翻转特效的方法
2015/02/17 Javascript
使用HTML5+Boostrap打造简单的音乐播放器
2016/08/05 Javascript
JavaScript面向对象编写购物车功能
2016/08/19 Javascript
JS 根据子网掩码,网关计算出所有IP地址范围示例
2020/04/23 Javascript
bootstrap table使用入门基本用法
2017/05/24 Javascript
微信小程序对接七牛云存储的方法
2017/07/30 Javascript
基于BootStrap的文本编辑器组件Summernote
2017/10/27 Javascript
JS实现小球的弹性碰撞效果
2017/11/11 Javascript
vue.js获得当前元素的文字信息方法
2018/03/09 Javascript
js实现动态增加文件域表单功能
2018/10/22 Javascript
vue在自定义组件中使用v-model进行数据绑定的方法
2019/03/25 Javascript
vue权限问题的完美解决方案
2019/05/08 Javascript
微信小程序之导航滑块视图容器功能的实现代码(简单两步)
2020/06/19 Javascript
python链接Oracle数据库的方法
2015/06/28 Python
Python基于有道实现英汉字典功能
2015/07/25 Python
打包python 加icon 去掉cmd黑窗口方法
2019/06/24 Python
keras tensorflow 实现在python下多进程运行
2020/02/06 Python
python实现移动木板小游戏
2020/10/09 Python
意大利在线药房:Farmacia Loreto Gallo
2019/08/09 全球购物
一套软件开发工程师笔试题
2015/05/18 面试题
兼职业务员岗位职责
2014/01/01 职场文书
营销总经理岗位职责范本
2014/09/02 职场文书
销售顾问工作计划书
2014/09/15 职场文书
2014年建筑工作总结
2014/11/26 职场文书
英语复习计划
2015/01/19 职场文书
签字仪式主持词
2015/07/03 职场文书
遇事可以测出您的见识与格局
2019/09/16 职场文书