我们知道Python是一门面向对象的编程语言,既然面向对象就少不了继承。
继承:表示子类可以使用其父类中方法。
在Python中,可以通过super() 函数来调用父类的方法。
如下所示,我定义了一个 Person 类,有 说、唱、rap、篮球 这四个 方法。
class Person(): def speak(self): print('i can speak') def sing(self): print('i can sing') def rap(self): print('i can rap') def basketball(self): print('i can basketball')
def speak(self):
print('i can speak')
def sing(self):
print('i can sing')
def rap(self):
print('i can rap')
def basketball(self):
print('i can basketball')
如果只有一个类 直接实例化.函数名的方式进行调用即可。
假设我现在有个Student (学生类),同样也可以说、唱、Rap、篮球。如果再重新写一遍这四个函数就比较麻烦。因此这个时候就可以用到继承。学生类来继承Person类(也就是说Student是Person的子类,Person是Student的父类)
如下所示
# Student(Object) 括号中的类,表示要继承的类class Student(Person): pass# Student1(Object) 括号中的类,表示要继承的类class Student1(Person): def study(self): print('i like study')if __name__ == '__main__': # 实例化一个Student对象 s = Student() s.rap() # i can rap s.basketball() # i can basketball s1 = Student1() s1.rap() # i can rap s1.study() # i like study
class Student(Person):
pass
# Student1(Object) 括号中的类,表示要继承的类
class Student1(Person):
def study(self):
print('i like study')
if __name__ == '__main__':
# 实例化一个Student对象
s = Student()
s.rap() # i can rap
s.basketball() # i can basketball
s1 = Student1()
s1.rap() # i can rap
s1.study() # i like study
Student、Student1 都继承了Person类。
Student只会 说、唱、rap、篮球。而Student1 还喜欢学习。可以再定义一个study函数。
上面只是用简单的代码介绍了一下Python中的继承。还没有说到如何用super()来调用父类的方法。
在子类中如果需要去掉用父类的方法时,可以通过 super(). 父类方法 的形式完成。
示例:
class A: def get_name(self): return 'my name is xiaoming'class B(A): def my_info(self): print('i am 18 years old') # 通过super() 函数 调用父类A 中的get_name函数,返回字符串 print(super().get_name()) print('i like rap and basketball')if __name__ == '__main__': b = B() """ 输出: i am 18 years old my name is xiaoming i like rap and basketball """ b.my_info()
def get_name(self):
return 'my name is xiaoming'
class B(A):
def my_info(self):
print('i am 18 years old')
# 通过super() 函数 调用父类A 中的get_name函数,返回字符串
print(super().get_name())
print('i like rap and basketball')
if __name__ == '__main__':
b = B()
"""
输出:
i am 18 years old
my name is xiaoming
i like rap and basketball
"""
b.my_info()
在B方法中调用my_info 时,可以直接通过父类A中的get_name 方法 获取到名字。
问题: 如果一个子类继承了两个父类,并且父类中的方法名相同。那究竟会调用哪个类呢?
这个问题可以通过类的内置属性 __mro__ 去查看调用顺序。这个方法主要是在多继承时判断方法、属性的调用路径。
class A: num = 1 def method(self): print('A ..method')class B: num = 2 def method(self): print('B .. method')class C(A, B): num = 3 passif __name__ == '__main__': c = C() print(C.__mro__) # (<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>) print(c.num) # 3 c.method() # A ..method
num = 1
def method(self):
print('A ..method')
class B:
num = 2
def method(self):
print('B .. method')
class C(A, B):
num = 3
pass
if __name__ == '__main__':
c = C()
print(C.__mro__) # (<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
print(c.num) # 3
c.method() # A ..method
如上,C.__mro__ 打印结果可以执行顺序为 C -> A - >B
因此print(c.num)。因为c中有num属性,所以会打印3.
执行c.method时 。因为c中没有method属性,会去A中查找,则输出 A..method。