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设置windows桌面壁纸的实现代码
Jan 28 Python
在Django框架中编写Context处理器的方法
Jul 20 Python
基于Python 的进程管理工具supervisor使用指南
Sep 18 Python
Python快速查找list中相同部分的方法
Jun 27 Python
Python爬虫框架Scrapy基本用法入门教程
Jul 26 Python
Python 实现异步调用函数的示例讲解
Oct 14 Python
selenium+python自动化测试之使用webdriver操作浏览器的方法
Jan 23 Python
Python学习笔记基本数据结构之序列类型list tuple range用法分析
Jun 08 Python
安装完Python包然后找不到模块的解决步骤
Feb 13 Python
python开发实例之python使用Websocket库开发简单聊天工具实例详解(python+Websocket+JS)
Mar 18 Python
解决python pandas读取excel中多个不同sheet表格存在的问题
Jul 14 Python
Python 的演示平台支持 WSGI 接口的应用
Apr 20 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 Google的translate API代码
2008/12/10 PHP
php设计模式 Proxy (代理模式)
2011/06/26 PHP
PHP中include和require的区别实例分析
2017/05/07 PHP
javascript 打印页面代码
2009/03/24 Javascript
JS获取dom 对象 ajax操作 读写cookie函数
2009/11/18 Javascript
详解JavaScript中undefined与null的区别
2014/03/29 Javascript
JavaScript link方法入门实例(给字符串加上超链接)
2014/10/17 Javascript
jQuery创建DOM元素实例解析
2015/01/19 Javascript
使用mouse事件实现简单的鼠标经过特效
2015/01/30 Javascript
JavaScript实现自动变换表格边框颜色
2015/05/08 Javascript
javascript从定义到执行 你不知道的那些事
2016/01/04 Javascript
jquery实现拖动效果
2016/08/10 Javascript
jquery select2的使用心得(推荐)
2016/12/04 Javascript
BootStrap中jQuery插件Carousel实现轮播广告效果
2017/03/27 jQuery
angular 用拦截器统一处理http请求和响应的方法
2017/06/08 Javascript
微信小程序实现slideUp、slideDown滑动效果及点击空白隐藏功能示例
2018/12/11 Javascript
微信小程序实现购物页面左右联动
2019/02/15 Javascript
vue多个元素的样式选择器问题
2019/11/29 Javascript
[06:01]刀塔次级联赛top10第一期
2014/11/07 DOTA
Python def函数的定义、使用及参数传递实现代码
2014/08/10 Python
使用Python实现简单的服务器功能
2017/08/25 Python
Python动刷新抢12306火车票的代码(附源码)
2018/01/24 Python
python实现电子书翻页小程序
2019/07/23 Python
python使用pip安装SciPy、SymPy、matplotlib教程
2019/11/20 Python
Python PyQt5运行程序把输出信息展示到GUI图形界面上
2020/04/27 Python
CSS3 函数技巧 用css 实现js实现的事情(clac Counters Tooltip)
2017/08/15 HTML / CSS
解决canvas转base64/jpeg时透明区域变成黑色背景的方法
2016/10/23 HTML / CSS
优瑞自动咖啡机官网:Jura
2018/09/29 全球购物
小学生寒假家长评语
2014/04/16 职场文书
晋江市委常委班子四风问题整改工作方案
2014/10/26 职场文书
学生检讨书
2015/01/27 职场文书
教师创先争优承诺书
2015/04/27 职场文书
煤矿安全生产工作总结
2015/08/13 职场文书
《七月的天山》教学反思
2016/02/19 职场文书
MYSQL 运算符总结
2021/11/11 MySQL
在js中修改html body的样式
2021/11/11 Javascript