python基础day33 单继承和多继承下的属性查找和组合
单继承下的属性查找
# 单继承的意思是一个类只继承一个类 class D(): pass class C(D): pass class B(C): pass class A(B): pass """python支持多继承""" class D(): pass class C(D): pass class B(C): pass class A(B,C,D): pass # 如何查找继承下的属性和方法呢class Foo(): def f1(self): print("Foo.f1") def f2(self): obj: print("Foo.f2") self.f1()class Bar(Foo): def f1(self): print("Bar.f1") # """单继承下的属性查找顺序:先从对象自己的名称空间中查找,然后去产生这个对象的类中查找,最后在去继承的父类中查找"""obj = Bar()obj.f2() # obj.f2(obj) class Foo(): def __f1(self): # _Foo__f1() print("Foo.f1") def f2(self): # obj: print("Foo.f2") self.__f1() # self._Foo__f1() class Bar(Foo): def __f1(self): # _Bar__f1() print("Bar.f1") """单继承下的属性查找顺序:先从对象自己的名称空间中查找,然后去产生这个对象的类中查找,最后在去继承的父类中查找""" obj = Bar() obj.f2() # obj.f2(obj)
多继承下的属性查找
# 一个类可以继承多个类 """python支持多继承""" class D(): pass class C(D): pass class B(C, D): pass class A(B,C,D): pass
多继承下的属性查找分为:
菱形查找:
非菱形查找:
菱形查找分:经典类和新式类
经典类:按照深度优先查询
新式类:按照广度优先查询
ps:在python3中都是新式类,所以多继承下的属性查找,如果属性找不到,就按照广度优先查询
一般情况下,最好不要使用多继承
drf中的多继承很好明白
super关键字的使用
class A: def test(self): super().test() class B: def test(self): print('from B') class C(A, B): pass # c = C() # c.test() # from B a = A() a.test()
mro列表
mro列表就是C类的属性查找顺序
ps:如果你继承的类中出现了super()关键字的用法,就要使用mro列表来查找属性
print(C.mro()) # [<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>] print(A.mro()) # [<class '__main__.A'>, <class 'object'>] print(A.__mro__)
多态和多态性(理论)
多态:一种事物的多种形态
eg:
水:液态水、气态水、固态水
动物:人、狗、猫、猪...
# 如何在父类里面强制限制子类中必须有speak功能 class Animal(): def speak(): pass class People(Animal): def speak(): pass class Dog(Animal): def speak(): pass class Pig(Animal): def speak(): pass obj = People() obj.speak() # 强制限制 import abc # abstract 抽象的 # 这个类就变成了:抽象类 # 抽象类的特点:只能被继承,不能被实例化! # 抽象类中的方法都是抽象方法,而抽象方法不再实现具体的功能,而是用来限制子类的行为 """强制限制,这种方式是python不推荐的,python推荐的是鸭子类型""" class Animal(metaclass=abc.ABCMeta): @abc.abstractmethod # 抽象方法 def speak(self): pass @abc.abstractmethod def jiao(self): pass class People(Animal): def speak(self): pass ... class Dog(Animal): def speak(self): pass class Pig(Animal): def speak(self): pass obj = People() obj1 = Dog() obj.speak() obj1.speak()
组合
# 组合它不是一个新技术,就是之前我们学习的知识点 组合:就是一个对象拥有一个属性,该属性的值是另外一个对象 class Foo(): def __init__(self, m): self.m = m class Bar(): def __init__(self, n): self.n = n obj = Foo(10) obj1 = Bar(20) """obj对象就是一个超级对象,通过一个对象可以得到另外一个对象的值""" obj.x = obj1 # obj.x ---------> obj1 print(obj1.n) # print(obj.x.n) print(obj.x.n) # print(obj1.n) class People(): def __init__(self, name, age, gender): """这个是指名道姓的调用方法,不依赖于继承""" self.name = name self.age = age self.gender = gender """ 继承一般用在什么是什么的时候 组合一般用在什么有什么的时候 """ class Course(): def __init__(self, course_name, course_price, course_period): """这个是指名道姓的调用方法,不依赖于继承""" self.course_name = course_name self.course_price = course_price self.course_period = course_period python=Course("python", 10000, '6mon') linux = Course("linux", 20000, '5mon') class Student(People): def __init__(self, name, age, gender, course=None): if course is None: course = [] """这个是指名道姓的调用方法,不依赖于继承""" super(Student, self).__init__( name, age, gender) self.courses = course def choose_course(self): pass stu = Student('kevin', '19', 'male') # print(stu.course_name) # print(stu.course_price) stu.courses.append(python) # stu.courses ====> [python对象] stu.courses.append(linux) # stu.courses ====> [python对象, linux对象] print(stu.courses)