51Testing软件测试论坛

标题: Python3 学习笔记 -- 继承 [打印本页]

作者: 小小糖    时间: 2018-4-23 13:44
标题: Python3 学习笔记 -- 继承
先上一个比较简单的单继承语法。在python3中,基类的构造函数不会被自动调用,需要手动调用,同样的
方法也是这样,需要手动调用。可以使用类名称+init方法,也可以使用super语法进行调用。在下面这个例子
中,子类继承了基类的方法和字段。字段会在基类中初始化。



  1. class BaseClass:   
  2.     def __init__(self):
  3.         self.name = 'BaseClass'
  4.         print('BaseCalss: Constructor called')
  5.     def getname(self):
  6.         print('BaseCalss: self name equals ' + self.name)

  7. class DerivedClass(BaseClass):
  8.     def __init__(self):
  9.         super().__init__()
  10.         print('DerivedClass: Constructor called')

  11. if __name__ == '__main__':
  12.     class1 = BaseClass()
  13.     class1.getname()
  14.    
  15.     class2 = DerivedClass()
  16.     class2.getname()
  17. 运行结果:

  18. BaseCalss: Constructor called
  19. BaseCalss: self name equals BaseClass
  20. BaseCalss: Constructor called
  21. DerivedClass: Constructor called
  22. BaseCalss: self name equals BaseClass


  23. 子类也可以overwrite父类的方法,那么父类的方法就不会被调用,除非手动调用:

  24. class BaseClass:   
  25.     def __init__(self):
  26.         self.name = 'BaseClass'
  27.         print('BaseCalss: Constructor called')
  28.     def getname(self):
  29.         print('BaseCalss: self name equals ' + self.name)

  30. class DerivedClass(BaseClass):
  31.     def __init__(self):
  32.         super().__init__()
  33.         print('DerivedClass: Constructor called')
  34.     def getname(self):
  35.         print('self.name init value is ' + self.name)
  36.         self.name = 'DerivedClass'
  37.         print('DerivedClass: self name equals ' + self.name)

  38. if __name__ == '__main__':
  39.     class1 = BaseClass()
  40.     class1.getname()
  41.    
  42.     class2 = DerivedClass()
  43.     class2.getname()
复制代码


运行结果:

BaseCalss: Constructor called
BaseCalss: self name equals BaseClass
BaseCalss: Constructor called
DerivedClass: Constructor called
self.name init value is BaseClass
DerivedClass: self name equals DerivedClass



python不仅仅支持单继承,还支持多继承,字段和方法都可以被继承。在多继承super()只能代表继承的第
一个父类,所以您在子类的构造函数中,不能单独使用super().__init__(), 那只是表示调用其中一个基类的
构造函数。所以用super就不是那么好用了。还是要用会原来的类名+init方法来调用。

  1. class BaseClass1:
  2.     def __init__(self):
  3.         self.name1 = 'BaseClass1_Name1'
  4.         self.name = 'BaseClass1_Name'
  5.         print('BaseCalss1: Constructor called')
  6.     def getname1(self):
  7.         print('BaseCalss1: self name1 equals ' + self.name1)
  8.     def getname(self):
  9.         print('BaseCalss1: getname called, name equal ' + self.name)

  10. class BaseClass2:
  11.     def __init__(self):
  12.         self.name2 = 'BaseClass2_Name2'
  13.         self.name = 'BaseClass2_Name'
  14.         print('BaseClass2: Constructor called')
  15.     def getname2(self):
  16.         print('BaseClass2: self name2 equals ' + self.name2)
  17.     def getname(self):
  18.         print('BaseCalss2: getname called, name equal ' + self.name)

  19. class DerivedClass2(BaseClass1, BaseClass2):
  20.     def __init__(self):
  21.         BaseClass1.__init__(self)
  22.         BaseClass2.__init__(self)
  23.         print('DerivedClass: Constructor called')
  24.         
  25. if __name__ == '__main__':
  26.     class1 = BaseClass1()
  27.     class1.getname1()
  28.    
  29.     class2 = BaseClass2()
  30.     class2.getname2()
  31.    
  32.     class3 = DerivedClass2()
  33.     class3.getname1()
  34.     class3.getname2()
  35.     class3.getname()
  36. 运行结果:

  37. BaseCalss1: Constructor called
  38. BaseCalss1: self name1 equals BaseClass1_Name1
  39. BaseClass2: Constructor called
  40. BaseClass2: self name2 equals BaseClass2_Name2
  41. BaseCalss1: Constructor called
  42. BaseClass2: Constructor called
  43. DerivedClass: Constructor called
  44. BaseCalss1: self name1 equals BaseClass1_Name1
  45. BaseClass2: self name2 equals BaseClass2_Name2
  46. BaseCalss1: getname called, name equal BaseClass2_Name
复制代码




我们可以看到,当两个基类有方法重名的时候,python3会按照您继承类的从左到右的顺序查找您调用的方
法DerivedClass2(BaseClass1, BaseClass2)。在这个例子中,是先找BaseClass1,然后再找BaseClass2。

如果您的代码需要多层继承的话,可以参开多重继承的 Diamond Problem 问题。

  1. class A1:
  2.     def foo1(self):
  3.         print("Call A1's foo1")
  4. class A2:
  5.     def foo1(self):
  6.         print("Call A2's foo1")
  7.     def foo2(self):
  8.         print("Call A2's foo2")

  9. class B1(A1,A2):
  10.     pass
  11. class B2(A1,A2):
  12.     def foo2(self):
  13.         print("Call B2's foo2")
  14.         
  15. class C(B1,B2):
  16.     pass

  17. if __name__ == '__main__':
  18.    
  19.     class1 = C()
  20.     class1.foo1()
  21.     class1.foo2()
复制代码


运行结果:

Call A1's foo1
Call B2's foo2

所以对于python3 的多层继承来说,因为都是新式类,总是从左到右,广度优先的方式进行。


作者: 梦想家    时间: 2018-5-9 10:00





欢迎光临 51Testing软件测试论坛 (http://bbs.51testing.com/) Powered by Discuz! X3.2