`
rockkyle
  • 浏览: 10323 次
最近访客 更多访客>>
社区版块
存档分类
最新评论

super 总结

 
阅读更多

一、在Python类的方法(method)中,要调用父类的某个方法,可以有如下写法

class A(object):
        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

 如果B的父类改变为C,如上例子只需要修改2处而已(将B类中的A换成C),这种调用方法在代码量大的情况下不可取,即引入super机制

官网解释super(type[, object-or-type]):

返回type的父类,如果第二个参数遗漏,则父类是非绑定的,如果第二个参数为object,则isinstance(obj,type)需为真,如果第二个参数为type,则issubclass(type2,type)需为真,super()必须作用于新式类。

 

改写如下(绑定),其中self是B的一个实例:

class A(object):
        def __init__(self):
                print "enter A"
                print "leave A"
class B(A):
        def __init__(self):
                print "enter B"
                super(B,self).__init__()
                print "leave B"

b=B()
二、多重继承情况:
非绑定情况
class A(object):
        def __init__(self):
                print "enter A"
                print "leave A"
class B(A):
        def __init__(self):
                print "enter B"
                A.__init__(self)
                print "leave B"
class C(B,A):
        def __init__(self):
                print "enter C"
                B.__init__(self)
                A.__init__(self)
                print "leave C"
c=C()
 
enter C
enter B
enter A
leave A
leave B
enter A
leave A
leave C
 看出A被调了2次,改用super,
class A(object):
        def __init__(self):
                print "enter A"
                print "leave A"
class B(A):
        def __init__(self):
                print "enter B"
                super(B,self).__init__()
                print "leave B"
class C(B,A):
        def __init__(self):
                print "enter C"
                super(C,self).__init__()
                print "leave C"
c=C()
 结果:
enter C
enter B
enter A
leave A
leave B
leave C
 这里只被调用一次
三、多重继承机制
python super多重继承机制为mro(Method resolution order)
比如上面的例子MRO即为 C B A ,super调用的为MRO中的下一个方法
class A(object):
  2     def __init__(self):
  3         print "A"
  4         super(A,self).__init__()
  5 class B(object):
  6     def __init__(self):
  7         print "B"
  8         super(B,self).__init__()
  9 class C(A):
 10     def __init__(self,arg):
 11         print "c","arg=",arg
 12         super(C,self).__init__()
 13 class D(B):
 14     def __init__(self,arg):
 15         print "D","arg=",arg
 16         super(D,self).__init__()
 17 
 18 class E(C,D):
 19     def __init__(self,arg):
 20         print "E","arg=",arg
 21         super(E,self).__init__(arg)
 22 E(1)
 期望输出:
E arg=1
C arg=1
A
D arg=1
E
实际输出
E arg= 10
c arg= 10
A
Traceback (most recent call last):
  File "super_test.py", line 22, in <module>
    E(10)
  File "super_test.py", line 21, in __init__
    super(E,self).__init__(arg)
  File "super_test.py", line 12, in __init__
    super(C,self).__init__()
  File "super_test.py", line 4, in __init__
    super(A,self).__init__()
TypeError: __init__() takes exactly 2 arguments (1 given)
 首先 MRO顺序为E C A D B
调用继续到A.__init__时,我们调用了super(A,self).__init__,其实调用了mro中下一个类型的方法,也就是
D中的__init__,由于D的 __init__带有1个参数,所以报错
所以如果要解决参数匹配的问题,建议采用*arg,**kwargs作为参数,所有的类也都采用super
 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics