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实现360的字符显示界面
Feb 21 Python
python中实现php的var_dump函数功能
Jan 21 Python
Python中编写ORM框架的入门指引
Apr 29 Python
Python做文本按行去重的实现方法
Oct 19 Python
Tensorflow中使用tfrecord方式读取数据的方法
Jun 19 Python
如何利用Boost.Python实现Python C/C++混合编程详解
Nov 08 Python
python lxml中etree的简单应用
May 10 Python
opencv转换颜色空间更改图片背景
Aug 20 Python
python 中的9个实用技巧,助你提高开发效率
Aug 30 Python
Python+Appium实现自动抢微信红包
May 21 Python
一文搞懂python异常处理、模块与包
Jun 26 Python
python实现对doc、txt、xls等文档的读写操作
Apr 02 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 柱状图实现代码
2009/12/04 PHP
php 处理上百万条的数据库如何提高处理查询速度
2010/02/08 PHP
qq登录,新浪微博登录接口申请过程中遇到的问题
2014/07/22 PHP
2017年最好用的9个php开发工具推荐(超好用)
2017/10/23 PHP
PHP静态方法和静态属性及常量属性的区别与介绍
2019/03/22 PHP
javascript一些不错的函数脚本代码
2008/09/10 Javascript
js 判断 enter 事件
2009/02/12 Javascript
用JavaScript实现单继承和多继承的简单方法
2009/03/29 Javascript
javascript游戏开发之《三国志曹操传》零部件开发(二)人物行走的实现
2013/01/23 Javascript
jquery中使用$(#form).submit()重写提交表单无效原因分析及解决
2013/03/25 Javascript
js setTimeout()函数介绍及应用以倒计时为例
2013/12/12 Javascript
HTML页面登录时的JS验证方法
2014/05/28 Javascript
jQuery获取节点和子节点文本的方法
2014/07/22 Javascript
javascript格式化json显示实例分析
2015/04/21 Javascript
Vue.js数据绑定之data属性
2017/07/07 Javascript
微信小程序中button组件的边框设置的实例详解
2017/09/27 Javascript
基于js中style.width与offsetWidth的区别(详解)
2017/11/12 Javascript
vue-router之nuxt动态路由设置的两种方法小结
2018/09/26 Javascript
JavaScript箭头函数中的this详解
2019/06/19 Javascript
R vs. Python 数据分析中谁与争锋?
2017/10/18 Python
点球小游戏python脚本
2018/05/22 Python
解决python3 Pycharm上连接数据库时报错的问题
2018/12/03 Python
浅谈Pycharm中的Python Console与Terminal
2019/01/17 Python
使用python-cv2实现Harr+Adaboost人脸识别的示例
2020/10/27 Python
如何用tempfile库创建python进程中的临时文件
2021/01/28 Python
保险专业大专生求职信
2013/10/26 职场文书
自荐书封面下载
2013/11/29 职场文书
求职面试个人自我评价
2014/02/28 职场文书
2014年学生工作总结
2014/11/20 职场文书
2015年预备党员自我评价
2015/03/04 职场文书
乡镇安全生产月活动总结
2015/05/08 职场文书
2015年会计人员工作总结
2015/05/22 职场文书
员工担保书范本
2015/09/22 职场文书
如何用JavaScript学习算法复杂度
2021/04/30 Javascript
Python List remove()实例用法详解
2021/08/02 Python
面试官问我Mysql的存储引擎了解多少
2022/08/05 MySQL