Python中super关键字用法实例分析


Posted in Python onMay 28, 2015

本文实例讲述了Python中super关键字用法。分享给大家供大家参考。具体分析如下:

在Python类的方法(method)中,要调用父类的某个方法,在Python 2.2以前,通常的写法如代码段1:

代码段1:

class A:
def __init__(self):
  print "enter A"
  print "leave A"
class B(A):
def __init__(self):
  print "enter B"
  A.__init__(self)
  print "leave B"
>>> b = B()

enter B
enter A
leave A
leave B

即,使用非绑定的类方法(用类名来引用的方法),并在参数列表中,引入待绑定的对象(self),从而达到调用父类的目的。

这样做的缺点是,当一个子类的父类发生变化时(如类B的父类由A变为C时),必须遍历整个类定义,把所有的通过非绑定的方法的类名全部替换过来,例如代码段2,

代码段2:

class B(C):  # A --> C
def __init__(self):
  print "enter B"
  C.__init__(self) # A --> C
  print "leave B"

如果代码简单,这样的改动或许还可以接受。但如果代码量庞大,这样的修改可能是灾难性的。很容易导致修改错误的出现。

因此,自Python 2.2开始,Python添加了一个关键字super,来解决这个问题。下面是Python 2.3的官方文档说明:

super(type[, object-or-type])
Return the superclass of type. If the second argument is omitted the super object
returned is unbound. If the second argument is an object, isinstance(obj, type) 
must be true. If the second argument is a type, issubclass(type2, type) must be 
true. super() only works for new-style classes.
A typical use for calling a cooperative superclass method is:
  class C(B):
    def meth(self, arg):
      super(C, self).meth(arg)
New in version 2.2.

从说明来看,可以把类B改写如代码段3:

代码段3:

class A(object):  # A must be new-style class
def __init__(self):
  print "enter A"
  print "leave A"
class B(C):   # A --> C
def __init__(self):
  print "enter B"
  super(B, self).__init__()
  print "leave B"

尝试执行上面同样的代码,结果一致,但修改的代码只有一处,把代码的维护量降到最低,是一个不错的用法。因此在我们的开发过程中,super关键字被大量使用,而且一直表现良好。

1. super并不是一个函数,是一个类名,形如super(B, self)事实上调用了super类的初始化函数,产生了一个super对象;

2. super类的初始化函数并没有做什么特殊的操作,只是简单记录了类类型和具体实例;

3. super(B, self).func的调用并不是用于调用当前类的父类的func函数;

4. Python的多继承类是通过mro的方式来保证各个父类的函数被逐一调用,而且保证每个父类函数只调用一次(如果每个类都使用super);

5. 混用super类和非绑定的函数是一个危险行为,这可能导致应该调用的父类函数没有调用或者一个父类函数被调用多次。

从super关键字的help我们也能看出来。

Help on class super in module __builtin__:
class super(object)
 |  super(type) -> unbound super object
 |  super(type, obj) -> bound super object; requires isinstance(obj, type)
 |  super(type, type2) -> bound super object; requires issubclass(type2, type)
 |  Typical use to call a cooperative superclass method:
 |  class C(B):
 |      def meth(self, arg):
 |           super(C, self).meth(arg)
 | 
 |  Methods defined here:
.......

从上面也能看出来,super是一个类,而且是__builtin__模块中的。

从上面的描述来看,super主要是用于调用父类的方法。

那么,在2.2之前的方法也能调用。为啥非得用super呢?

这是因为super能够阻止对父类方法的多次调用。

super,改变了父类搜索顺序, 返回的是一个特殊的父类对象
看例子:

class A: pass class B(A): pass class C(A):pass class D(B, C): pass

这是4个类的基本关系。

假如不使用super,让D的对象调用他们共有的一个方法,会2次调用A中这个方法。

希望本文所述对大家的Python程序设计有所帮助。

Python 相关文章推荐
跟老齐学Python之编写类之二方法
Oct 11 Python
python中字符串类型json操作的注意事项
May 02 Python
python numpy数组的索引和切片的操作方法
Oct 20 Python
解决Pycharm下面出现No R interpreter defined的问题
Oct 29 Python
解决pycharm运行出错,代码正确结果不显示的问题
Nov 30 Python
PyQt4编程之让状态栏显示信息的方法
Jun 18 Python
python 一个figure上显示多个图像的实例
Jul 08 Python
详解Flask前后端分离项目案例
Jul 24 Python
Django windows使用Apache实现部署流程解析
Oct 12 Python
让你相见恨晚的十个Python骚操作
Nov 18 Python
Pycharm plot独立窗口显示的操作
Dec 11 Python
python 实现图与图之间的间距调整subplots_adjust
May 21 Python
Python使用Supervisor来管理进程的方法
May 28 #Python
Python运算符重载用法实例
May 28 #Python
Python smallseg分词用法实例分析
May 28 #Python
Python基于smtplib实现异步发送邮件服务
May 28 #Python
Python使用Scrapy爬取妹子图
May 28 #Python
Python实现统计单词出现的个数
May 28 #Python
Python下载懒人图库JavaScript特效
May 28 #Python
You might like
php基于base64解码图片与加密图片还原实例
2014/11/03 PHP
超详细的php用户注册页面填写信息完整实例(附源码)
2015/11/17 PHP
jquery高效反选具体实现
2013/05/05 Javascript
可自己添加html的伪弹出框实现代码
2013/09/08 Javascript
对 jQuery 中 data 方法的误解分析
2014/06/18 Javascript
JS实现控制表格行文本对齐的方法
2015/03/30 Javascript
用JavaScript来美化HTML的select标签的下拉列表效果
2015/11/17 Javascript
利用策略模式与装饰模式扩展JavaScript表单验证功能
2017/02/14 Javascript
jQuery实现的动态文字变化输出效果示例【附演示与demo源码下载】
2017/03/24 jQuery
js实现抽奖效果
2017/03/27 Javascript
jquery拖动改变div大小
2017/07/04 jQuery
vue表单绑定实现多选框和下拉列表的实例
2017/08/12 Javascript
利用JavaScript的%做隔行换色的实例
2017/11/25 Javascript
记一次webpack3升级webpack4的踩坑经历
2018/06/12 Javascript
详解关于Vue版本不匹配问题(Vue packages version mismatch)
2018/09/17 Javascript
Vue和React组件之间的传值方式详解
2019/01/31 Javascript
使用Vue.set()方法实现响应式修改数组数据步骤
2019/11/09 Javascript
JavaScript 获取滚动条位置并将页面滑动到锚点
2021/02/08 Javascript
python 文件与目录操作
2008/12/24 Python
Python中字典的基本知识初步介绍
2015/05/21 Python
更改Ubuntu默认python版本的两种方法python-> Anaconda
2016/12/18 Python
Windows下安装python2和python3多版本教程
2017/03/30 Python
在Python 字典中一键对应多个值的实例
2019/02/03 Python
python 实现在一张图中绘制一个小的子图方法
2019/07/07 Python
Django框架models使用group by详解
2020/03/11 Python
详解django使用include无法跳转的解决方法
2020/03/19 Python
突袭HTML5之Javascript API扩展5—其他扩展(应用缓存/服务端消息/桌面通知)
2013/01/31 HTML / CSS
使用canvas实现黑客帝国数字雨效果
2020/01/02 HTML / CSS
J2EE中常用的名词进行解释
2015/11/09 面试题
中职应届生会计求职信
2013/10/23 职场文书
城市轨道交通工程职业规划书范文
2014/01/18 职场文书
小学数学教师研修日志
2015/11/13 职场文书
JavaScript实现贪吃蛇游戏
2021/06/16 Javascript
Python实现照片卡通化
2021/12/06 Python
Nginx的基本概念和原理
2022/03/21 Servers
Li list-style-image 图片垂直居中实现方法
2023/05/21 HTML / CSS