一、前言
Python 面向对象中有继承这个概念,初学时感觉很牛逼,里面也有个super类,经常见到,最近做一些题才算是理解了。特地记录分享给后来研究的小伙伴,毕竟现在小学生都开始学了(滑稽脸)
二、代码
直接上干货,能把下面一个问题全答对,后面就不用看了。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
class A():
def go( self ):
print ( "go A go!" )
def stop( self ):
print ( "stop A stop!" )
def pause( self ):
raise Exception( "Not Implemented" )
class B(A):
def go( self ):
super (B, self ).go()
print ( "go B go!" )
class C(A):
def go( self ):
super (C, self ).go()
print ( "go C go!" )
def stop( self ):
super (C, self ).stop()
print ( "stop C stop!" )
class D(B,C):
def go( self ):
super (D, self ).go()
print ( "go D go!" )
def stop( self ):
super (D, self ).stop()
print ( "stop D stop!" )
def pause( self ):
print ( "wait D wait!" )
class E(B,C):
pass
a = A()
b = B()
c = C()
d = D()
e = E()
# 说明下列代码的输出结果
a.go()
print ( '--------' )
b.go()
print ( '--------' )
c.go()
print ( '--------' )
d.go()
print ( '--------' )
e.go()
print ( '--------' )
a.stop()
print ( '--------' )
b.stop()
print ( '--------' )
c.stop()
print ( '--------' )
d.stop()
print ( '--------' )
e.stop()
print (D.mro())
a.pause()
b.pause()
c.pause()
d.pause()
e.pause()
|
当然,直接运行就有答案了,还是要仔细想一下,反正看到我第一次跑出的结果的时候,我都不敢相信自己的眼睛。
step1:
几个概念:
继承的功能:父类的代码重用
多态的功能:同一方法对不同类型的对象会有相应的结果
开闭原则:对扩展开放,对修改封闭
super类功能:新式类实现广度优先的不重复的调用父类,解决了钻石继承(多继承)的难题
step2:
super实现原理:通过c3算法,生成mro(method resolution order)列表,根据列表中元素顺序查询调用
新式类调用顺序为广度优先,旧式类为深度优先
step3:
个人理解:
1.调用了父类的方法,出入的是子类的实例对象
2.新式类子类(A,B),A就在B之前
3.super类似于嵌套的一种设计,当代码执行到super实例化后,先去找同级父类,若没有其余父类,再执行自身父类,再往下走,
简洁点的三个原则就是:
子类在父类前,所有类不重复调用,从左到右
理解了以上的说法,题目就没问题了。
也不用跑了,答案如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
a.go() # go A go!
b.go() # go A go!# go B go!
c.go() # go A go!# go C go!
d.go() # go A go!# go C go!# go B go!# go D go!
e.go() # go A go!# go C go!# go B go!
a.stop() # stop A stop!
b.stop() # stop A stop!
c.stop() # stop A stop!# stop C stop!
d.stop() # stop A stop!# stop C stop!# stop D stop!
e.stop() # stop A stop!
a.pause() # ... Exception: Not Implemented
b.pause() # ... Exception: Not Implemented
c.pause() # ... Exception: Not Implemented
d.pause() # wait D wait!
e.pause() # ...Exception: Not Implemented
|
看了答案,其实还有一点,父类抛异常的情况,如果子类有不抛异常的方法,异常就不抛出了,这个设计也会很有用。
这里就中间一个A,C,B,D的和网上常见的不太一样,促使我仔细研究了一下,其实就是个人理解第三条。
补充:
Python2 和Python3在这个问题上的差别
Python2 没有默认继承object
Python3 默认全部继承object类,都是新式类
Python2super调用 super(开始类名,self).函数名()
Python3 super().函数名()
关于调用父类函数传入子类实例的栗子举一个:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
class A:
def __init__( self ):
self .n = 2
def add( self , m):
print ( 'self is {0} @A.add' . format ( self ))
self .n + = m
class B(A):
def __init__( self ):
self .n = 3
def add( self , m):
print ( 'self is {0} @B.add' . format ( self ))
super ().add(m)
print ( 'newb' )
self .n + = 3
class C(A):
def __init__( self ):
self .n = 4
def add( self , m):
print ( 'self is {0} @C.add' . format ( self ))
super ().add(m)
print ( 'newc' )
self .n + = 4
class D(B, C):
def __init__( self ):
self .n = 5
def add( self , m):
print ( 'self is {0} @D.add' . format ( self ))
super ().add(m)
self .n + = 5
d = D()
d.add( 2 )
print (d.n)
|
总结
以上所述是小编给大家介绍的Python 关于supper 的 用法和原理,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对服务器之家网站的支持!
原文链接:https://www.cnblogs.com/xinghuaikang/archive/2018/02/28/8481712.html