Python中调用父类的同名方法



     Python中对象方法的定义很怪异,第一个参数一般都命名为self(相当于其它语言的this),用于传递对象本身,而在调用的时候则不必显式传递,系统会自动传递

举一个很常见的例子:

Python代码
  1. >>> class Foo:  
  2.     def bar(self, message):  
  3.         print(message)  
  4.   
  5. >>> Foo().bar("Hello, World.")  
  6. Hello, World.  

 
     当存在继承关系的时候,有时候需要在子类中调用父类的方法,此时最简单的方法是把对象调用转换成类调用,需要注意的是这时self参数需要显式传递,例如:

Python代码
  1. >>> class FooParent:  
  2.         def bar(self, message):  
  3.             print(message)  
  4.   
  5. >>> class FooChild(FooParent):  
  6.         def bar(self, message):  
  7.             FooParent.bar(self, message)  
  8.   
  9. >>> FooChild().bar("Hello, World.")  
  10. Hello, World.  

 
      这样做有一些缺点,比如说如果修改了父类名称,那么在子类中会涉及多处修改,另外,Python是允许多继承的语言,如上所示的方法在多继承时就需要重复写多次,显得累赘。为了解决这些问题,Python引入了super()机制,例子代码如下:



Python的super()机制:

Java代码   收藏代码
  1. >>> class FooParent:  
  2.         def bar(self, message):  
  3.             print(message)  
  4.   
  5.           
  6. >>> class FooChild(FooParent):  
  7.         def bar(self, message):  
  8.             super(FooChild, self).bar(message)  
  9.   
  10.           
  11. >>> FooChild().bar("Hello, World.")  
  12. Hello, World.  

 
     表面上看 super(FooChild, self).bar(message)方法和FooParent.bar(self, message)方法的结果是一致的,实际上这两种方法的内部处理机制大大不同,当涉及多继承情况时,就会表现出明显的差异来,直接给例子:

代码一:

Python代码  
  1. class A:  
  2.     def __init__(self):  
  3.         print("Enter A")  
  4.         print("Leave A")  
  5.   
  6. class B(A):  
  7.     def __init__(self):  
  8.         print("Enter B")  
  9.         A.__init__(self)  
  10.         print("Leave B")  
  11.   
  12. class C(A):  
  13.     def __init__(self):  
  14.         print("Enter C")  
  15.         A.__init__(self)  
  16.         print("Leave C")  
  17.   
  18. class D(A):  
  19.     def __init__(self):  
  20.         print("Enter D")  
  21.         A.__init__(self)  
  22.         print("Leave D")  
  23.   
  24. class E(B, C, D):  
  25.     def __init__(self):  
  26.         print("Enter E")  
  27.         B.__init__(self)  
  28.         C.__init__(self)  
  29.         D.__init__(self)  
  30.         print("Leave E")  
  31.   
  32. E()  

 
结果:

Enter E
Enter B
Enter A
Leave A
Leave B

Enter C
Enter A
Leave A
Leave C

Enter D
Enter A
Leave A
Leave D

Leave E

     执行顺序很好理解,唯一需要注意的是公共父类A被执行了多次。

代码二:

Python代码  
  1. class A:  
  2.     def __init__(self):  
  3.         print("Enter A")  
  4.         print("Leave A")  
  5.   
  6. class B(A):  
  7.     def __init__(self):  
  8.         print("Enter B")  
  9.         super(B, self).__init__()  
  10.         print("Leave B")  
  11.   
  12. class C(A):  
  13.     def __init__(self):  
  14.         print("Enter C")  
  15.         super(C, self).__init__()  
  16.         print("Leave C")  
  17.   
  18. class D(A):  
  19.     def __init__(self):  
  20.         print("Enter D")  
  21.         super(D, self).__init__()  
  22.         print("Leave D")  
  23.   
  24. class E(B, C, D):  
  25.     def __init__(self):  
  26.         print("Enter E")  
  27.         super(E, self).__init__()  
  28.         print("Leave E")  
  29.   
  30. E()  

 

结果:

Enter E
Enter B
Enter C
Enter D
Enter A
Leave A
Leave D
Leave C
Leave B
Leave E

在super机制里可以保证公共父类仅被执行一次,至于执行的顺序,是按照mro进行的(E.__mro__)。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值