# -*- coding: utf-8 -*-

# python:2.x

__author__ = 'Administrator'

#当使用多重继承层次结构时,再使用super的时候是非常危险的,主要是因为类的初始化,基类不在__init__中被隐式调用

#1滥用super和传统调用

#来自james knight(http://funm.net/super-harmful)示例中,类C使用__init__方法调用其基类,这样类B被调用2次

class A(object):

def __init__(self):

print 'A'

super(A,self).__init__()

class B(object):

def __init__(self):

print 'B'

super(B,self).__init__()

class C(A,B):

def __init__(self):

print 'C'

A.__init__(self)

B.__init__(self)

print 'MRO:',[x.__name__ for x in C.__mro__]#MRO: ['C', 'A', 'B', 'object']

C()

"""

C

A

B

B

------------

出现这样的情况是:C实例调用 了A.__init__(self),因而super(A,self).__init__()将调用B构造程序,换句话说,super应该被乃至整个类层次中

问题是有时候这样的层次结构一部分位于第三方代码中,许多由多重继承引入层次调用相关缺陷都可以在JAMES页面上找到,为了避免这样问题,应该问题是在

子类化之前看看__mro__特性,如果它不存在,处理就是一个旧式类,避免使用super可能更安全一些

如下:

"""

from SimpleHTTPServer import SimpleHTTPRequestHandler

#print SimpleHTTPRequestHandler.__mro__AttributeError: class SimpleHTTPRequestHandler has no attribute '__mro__'

"""

如果__mro__存在,则快速地看看每个mro所涉及的类的构造程序代码,如果到处都使用super,那非常好,也可以使用它,否则就试着保持一致性

collections.deque能够被安全地子类化,就可以使用super,因为它直接子类化了object

"""

from collections import deque

print deque.__mro__#(<type 'collections.deque'>, <type 'object'>)

#randeom.Random是一个存在于_random模块中另一个类封装器

from random import Random

print Random.__mro__#(<class 'random.Random'>, <type '_random.Random'>, <type 'object'>)

#Zope类,

"""

from zope.app.container.brower.adding import Adding as s

s.__mro__

官方:http://www.zope.com/

有兴趣的朋友可以浏览下

"""

#不同种类参数

#super用法另一个问题是初始化中参数传递,类在没有相同签名的情况下怎么调用其基类的__init__代码呢?

class Bases(object):

def __init__(self):

print 'bases'

super(Bases,self).__init__()

class B(Bases):

def __init__(self):

print 'B'

super(B,self).__init__()

class B1(Bases):

def __init__(self):

print 'b1'

super(B1,self).__init__()

class MyClass(B,B1):

def __init__(self,arg):

print 'my class arg'

super(MyClass,self).__init__(arg)

#m=MyClass(10)TypeError: __init__() takes exactly 1 argument (2 given)

#解决方法之下是使用*args,**kw魔法,所有构造程序将传递所有参数,即使不使用它们

class Bb(object):

def __init__(self,*args,**kw):

print 'b1'

super(Bb,self).__init__(*args,**kw)

class bb(Bb):

def __init__(self,*args,**kw):

print 'bb'

super(bb,self).__init__(*args,**kw)

class bbb(Bb):

def __init__(self,*args,**kw):

print 'bbb'

super(bbb,self).__init__(*args,**kw)

class MyclSS(bb,bbb):

def __init__(self,arg):

print 'myclss'

super(MyclSS,self).__init__(arg)

mm=MyclSS(10)

"""

myclss

bb

bbb

b1

"""

"""

但是这样是一个很糟糕的修复方法,因为它使所有构造程序将接受任何类型参数,导致代码变得很脆弱,因为任何参数被传递并且通过,另一种解决方法是在yclSS

中使用经典的__init__调用,但是这将会导致产生第一种缺陷

"""

python高级编程之超类02:super的缺陷的更多相关文章

  1. python高级编程:有用的设计模式1

    # -*- coding: utf-8 -*-__author__ = 'Administrator'#python高级编程:有用的设计模式#设计械是可复用的,某种程序上它对软件设计中觉问题提供的语言 ...

  2. python高级编程之列表推导式

    1. 一个简单的例子 在Python中,如果我们想修改列表中所有元素的值,可以使用 for 循环语句来实现. 例如,将一个列表中的每个元素都替换为它的平方: >>> L = [1, ...

  3. 第三章:Python高级编程-深入类和对象

    第三章:Python高级编程-深入类和对象 Python3高级核心技术97讲 笔记 3.1 鸭子类型和多态 """ 当看到一直鸟走起来像鸭子.游泳起来像鸭子.叫起来像鸭子 ...

  4. 第十章:Python高级编程-多线程、多进程和线程池编程

    第十章:Python高级编程-多线程.多进程和线程池编程 Python3高级核心技术97讲 笔记 目录 第十章:Python高级编程-多线程.多进程和线程池编程 10.1 Python中的GIL 10 ...

  5. python高级编程:有用的设计模式3

    # -*- coding: utf-8 -*-__author__ = 'Administrator'#python高级编程:有用的设计模式#访问者:有助于将算法从数据结构中分离出来"&qu ...

  6. python高级编程:有用的设计模式2

    # -*- coding: utf-8 -*- __author__ = 'Administrator' #python高级编程:有用的设计模式 #代理 """ 代理对一 ...

  7. python高级编程技巧

    由python高级编程处学习 http://blog.sina.com.cn/s/blog_a89e19440101fb28.html Python列表解析语法[]和生成 器()语法类似 [expr  ...

  8. python高级编程之选择好名称:完

    由于时间关系,python高级编程不在放在这边进行学习了,如果需要的朋友可以看下面的网盘进行下载 # # -*- coding: utf-8 -*- # # python:2.x # __author ...

  9. python高级编程读书笔记(一)

    python高级编程读书笔记(一) python 高级编程读书笔记,记录一下基础和高级用法 python2和python3兼容处理 使用sys模块使程序python2和python3兼容 import ...

随机推荐

  1. pyqt学习之列表管理器(网友提供)

    # -*- coding: utf-8 -*- __author__ = 'Administrator' import sys from PyQt4.QtCore import * from PyQt ...

  2. linux高级技巧:heartbeat+lvs(一)

    1.heartbeat一个简短的引论:        Heartbeat 项目是 Linux-HA project的一个组成部分,它实现了一个高可用集群系统.心跳服务和集群通信是高可用集群的两个关键组 ...

  3. Andriod Studio科学文章——4.常见问题解答有关编译

    1.android未安装支持库 只有编译,下面的例子演示了提样: Could not find any version that matches com.android.support:appcomp ...

  4. Sass函数--map

    MapSass 的 map 常常被称为数据地图,也有人称其为数组,是以 key:value 成对的出现. $map: ( $key1: value1, $key2: value2, $key3: va ...

  5. GDI+编程的10个基本技巧(转)

    创建绘图表面 创建绘图表面有两种常用的方法.下面设法得到PictureBox的绘图表面. private void Form1_Load(object sender, System.EventArgs ...

  6. (转)Div+CSS布局入门

    在网页制作中,有许多的术语,例如:CSS.HTML.DHTML.XHTML等等.在下面的文章中我们将会用到一些有关于HTML的基本知识,而在你学习这篇入门教程之前,请确定你已经具有了一定的HTML基础 ...

  7. rsync+inotify实时同步方案

    rsync+inotify实时同步,inotify可以实时监控本地文件或目录变化,当检测到本地文件变化,执行rsync同步命令,将变化的文件同步到其他服务器节点. 1.配置环境 3.在服务节点1.服务 ...

  8. hdu 畅通工程续

    算法:多源最短路(floyd) 题意:有多个城镇,有些之间有通路,给你起点和终点,输出最短路径: Problem Description 某省自从实行了很多年的畅通工程计划后,终于修建了很多路.不过路 ...

  9. Tornado 模板支持“控制语句”和“表达语句”的表现形式

    Tornado 的模板支持“控制语句”和“表达语句”,控制语句是使用 {% 和 %} 包起来的 例如 {% if len(items) > 2 %}.表达语句是使用 {{ 和 }} 包起来的,例 ...

  10. C#设置textboox只能输入数字`

    1.在闪电KeyPress事件中添加 private void textBox_pwmx_fre_KeyPress(object sender, KeyPressEventArgs e) { //如果 ...