最能感受到super函数的作用在于进行钻石继承的时候。
钻石继承:由一个基类衍生两个及以上的超类,然后在衍生,在类树的最底层生成一个子类,这样的类树结构就是一个类似 钻石外形,所以,最底层类继承称为钻石继承
首先:
这是直接通过超类调用方法给子类使用
class baseClass: num_base_calls = 0 def call_me(self): print("Calling method on Base Class") self.num_base_calls += 1 class leftSubClass(baseClass): num_left_calls = 0 def call_me(self): baseClass.call_me(self) print("Calling method on left SubClass") self.num_left_calls += 1 class rightSubClass(baseClass): num_right_calls = 0 def call_me(self): baseClass.call_me(self) print("Calling method on right SubClass") self.num_right_calls += 1 class SubClass(leftSubClass, rightSubClass): num_sub_calls = 0 def call_me(self): rightSubClass.call_me(self) leftSubClass.call_me(self) print("Calling method on SubClass") self.num_sub_calls += 1 s = SubClass() print(s.call_me()) print(s.num_sub_calls, s.num_left_calls, s.num_right_calls, s.num_base_calls)
结果是:
Calling method on Base Class Calling method on right SubClass Calling method on Base Class Calling method on left SubClass Calling method on SubClass 1 1 1 2
这是通过super()函数实现继承
class baseClass: num_base_calls = 0 def call_me(self): print("Calling method on Base Class") self.num_base_calls += 1 class leftSubClass(baseClass): num_left_calls = 0 def call_me(self): super().call_me() print("Calling method on left SubClass") self.num_left_calls += 1 class rightSubClass(baseClass): num_right_calls = 0 def call_me(self): super().call_me() print("Calling method on right SubClass") self.num_right_calls += 1 class SubClass(leftSubClass, rightSubClass): num_sub_calls = 0 def call_me(self): super().call_me() print("Calling method on SubClass") self.num_sub_calls += 1 # 使用super()实例化一个超类对象可以实现,每个层次只是进行且只进行一次调用 # 就拿这个例子来说 s = SubClass() print(s.call_me()) print(s.num_sub_calls, s.num_left_calls, s.num_right_calls, s.num_base_calls)
结果是:
Calling method on Base Class Calling method on right SubClass Calling method on left SubClass Calling method on SubClass 1 1 1 1
通过以上两个测试,第一个我们用超类直接调用他的方法在子类中实现了继承,但是我们看到这样的话每个超类都会在调用自身的call_me方法的同时也会调用超类的超类中的call_me方法,这样,baseClass就被执行了两次。第二个我们使用了super()方法在call_me方法中继承了超类的方法,这样就像注释里说的,它会根据继承的层次一个一个类的调用,所以baseClass类并不会被调用两次。这就是super()函数的作用
文章来源: python中的super()函数