在下面的例子中,如果我用CL2测试cl5中的self.test()替换CL2中的super,我得到相同的输出。超级究竟是如何产生任何不同的。
class CL1(object):
def test(self):
print "test cl1"
class CL2(CL1):
def abc(self):
print "in cl2"
super(CL2,self).test()
#self.test()
class CL3(CL1):
def test(self):
print "test cl3"
class CL5(CL1):
def test(self):
print "test cl5"
class CL4(CL2,CL5,CL3):
def add(self):
print 'cl4'
def main()
o=CL4()
o.abc()
if __name__ == "__main__":
main()
答案 0 :(得分:2)
如果您没有使用super
,那么在类CL2
内,它将隐式调用其父(CL1)的test()
方法。
但是当类CL2
也定义了一个名为test()
的方法(这在OOP中称为方法重写)时,会出现模糊问题。默认情况下使用的是当前类的test()
方法,但是如果要调用父类的方法,则需要使用super
显式调用其超类的test()
方法。
考虑这个例子:
class CL1(object):
def test(self):
print "test CL1"
class CL2(CL1):
def test(self):
print "test CL2"
def abc(self):
print "in CL2"
super(CL2,self).test()
self.test()
o=CL2()
o.abc()
将输出:
in CL2
test CL1
test CL2
答案 1 :(得分:-2)
super
不仅仅是方便将基类的名称留在子类方法之外;它是为协作继承而设计的,其中正确设计的类将根据C3线性化算法以正确的顺序调用overriden方法。
super
不一定是指您正在定义的类的静态声明的父级。请考虑以下代码:
class A:
def foo(self):
print("A.foo")
class B(A):
def foo(self):
print("B before super")
super().foo()
print("B.foo")
class C(A):
def foo(self):
print("C before super")
super().foo()
print("C.foo")
class D(B, C):
def foo(self):
print("D before super")
super().foo()
print("D.foo")
print(D.__mro__)
d = D()
d.foo()
运行super().foo()
时,B.foo
内的来电A.foo
不会致电d.foo()
;它会运行C.foo
,因为C
会在B
的方法解析顺序(MRO)D
之后立即出现。
如果您对B.foo
不是总是立即致电A.foo
不合适,无论self
的类型如何,请不要使用{{ 1}}。通过使用super
,您同意它旨在支持的语义,并且应该将该方法记录为使用super
。否则,只需使用super
,并使用A.foo(self)
记录您不的事实。