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 14 Python
Python用Bottle轻量级框架进行Web开发
Jun 08 Python
Python读取指定目录下指定后缀文件并保存为docx
Apr 23 Python
用python制作游戏外挂
Jan 04 Python
python使用代理ip访问网站的实例
May 07 Python
Python中if elif else及缩进的使用简述
May 31 Python
Python Numpy库安装与基本操作示例
Jan 08 Python
Python3.5装饰器典型案例分析
Apr 30 Python
对于Python深浅拷贝的理解
Jul 29 Python
使用 Python 写一个简易的抽奖程序
Dec 08 Python
Python reshape的用法及多个二维数组合并为三维数组的实例
Feb 07 Python
python通过函数名调用函数的几种方法总结
Jun 07 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验证码类代码( 最新修改,完全定制化! )
2010/12/02 PHP
php中mysql操作buffer用法详解
2015/03/19 PHP
添加到收藏夹代码(兼容几乎所有的浏览器)
2007/01/09 Javascript
用Javascript读取中文COOKIE的解决办法
2007/02/15 Javascript
JQuery UI皮肤定制
2009/07/27 Javascript
div移动 输入框不能输入的问题
2009/11/19 Javascript
jQuery实现密保互斥问题解决方案
2013/08/16 Javascript
javaScript如何处理从java后台返回的list
2014/04/24 Javascript
js实现顶部可折叠的菜单工具栏效果实例
2015/05/09 Javascript
AngularJS基础学习笔记之简单介绍
2015/05/10 Javascript
优化RequireJS项目的相关技巧总结
2015/07/01 Javascript
jQuery实现商品活动倒计时
2015/10/16 Javascript
jQuery实现网页顶部固定导航效果代码
2015/12/24 Javascript
JavaScript缓冲运动实现方法(2则示例)
2016/01/08 Javascript
基于javascript制作微博发布栏效果
2016/04/04 Javascript
BootStrap CSS全局样式和表格样式源码解析
2017/01/20 Javascript
Angular在一个页面中使用两个ng-app的方法(二)
2017/02/20 Javascript
基于JavaScript实现瀑布流效果
2017/03/29 Javascript
微信小程序使用scroll-view标签实现自动滑动到底部功能的实例代码
2018/11/09 Javascript
jquery.pager.js实现分页效果
2019/07/29 jQuery
快速了解Vue父子组件传值以及父调子方法、子调父方法
2020/07/15 Javascript
Python标准库内置函数complex介绍
2014/11/25 Python
Python3实现从指定路径查找文件的方法
2015/05/22 Python
PyQt5利用QPainter绘制各种图形的实例
2017/10/19 Python
python 获取微信好友列表的方法(微信web)
2019/02/21 Python
我们为什么要减少Python中循环的使用
2019/07/10 Python
python树的同构学习笔记
2019/09/14 Python
使用Python项目生成所有依赖包的清单方式
2020/07/13 Python
Python 解析库json及jsonpath pickle的实现
2020/08/17 Python
中东地区最大的奢侈品市场:The Luxury Closet
2019/04/09 全球购物
教育学专业实习生的自我鉴定
2013/11/26 职场文书
八项规定整改方案
2014/02/21 职场文书
市政管理求职信范文
2014/05/07 职场文书
支部书记四风对照材料
2014/08/28 职场文书
万里长城导游词
2015/01/30 职场文书
python将图片转为矢量图的方法步骤
2021/03/30 Python