单继承下的属性查找
单继承:一个类只能继承一个类。
class C():
pass class B(C): pass class A(B): # 单继承 pass
单继承下的属性查找顺序:
先从对象本身的名称空间中查找 ------> 产生这个对象的类中去查找 ------>继承的父类中去查找
# 查找属性 class Foo(): def f1(self): print('from f1') def f2(self): print('from f2') self.f1() # 此时,self = obj,所以调用Bar中的方法'f1' class Bar(Foo): # 单继承,继承Foo的所有属性 def f1(self): print('from Bar') obj = Bar() # 调用Bar产生一个 obj对象 obj.f2() # obj.f2() = obj.f2(obj) # from f2 # from Bar
练习题
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): print("Bar.f1") obj = Bar() obj.f2() # obj.f2(obj) # Foo.f2 # Foo.f1
多继承下的属性查找
多继承:一个类可以继承多个类,从左往右依次查找(python中支持多继承)
class D(): pass class C(D): pass class B(C,D): pass class A(B,C,D): pass
多继承下的属性查找分为:菱形查找、非菱形查找
经典类:按深度优先查找
新式类:按广度优先查找
# 多继承下的属性查找 class F(): def f(self): print('from F') class E(): def f(self): print('from E') class D(F): def f(self): print('from D') class C(E): ... # def f(self): # print('from C') class B(): ... # def f(self): # print('from B') class A(B,C,D): # def f(self): # print('from A') ... obj = A() print(A.mro()) # mro 打印出查找顺序 # 查找顺序:[<class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.E'>, <class '__main__.D'>, <class '__main__.F'>, <class 'object'>] obj.f() # from E
# 广度查找 class G(object): def test(self): print('from G') class E(G): def test(self): print('from E') class F(G): def test(self): print('from F') class B(E): def test(self): print('from B') class C(F): def test(self): print('from C') class D(G): def test(self): print('from D') class A(B, C, D): # def test(self): # print('from A') pass obj = A() print(A.mro()) # 打印A类的mro顺序 # [<class '__main__.A'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.F'>, <class '__main__.D'>, <class '__main__.G'>, <class 'object'>]
在python3 中都是新式类,所以多继承下的属性查找,如果属性查找不到,按广度优先的方式继续查找。
一般情况下,最好不使用多继承。
super关键字
super关键字的使用:当一个类没有继承另一个类的时候,继续按照mro列表来查找属性
# super关键字的使用 class A(): def f(self): super().f() #在A没有继承B的时候,继续按照mro列表继续往后走 class B(): def f(self): super().f() # 在B类没有继承C类,继续往下执行 class C(): def f(self): print('C') class D(A,B,C): pass obj = D() print(D.mro()) #[<class '__main__.D'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class 'object'>] obj.f() # C
多态与多态性
多态:一种事物的多种形态
多态性:多态带来的特性,就是在不考虑对象的类型的情况下,直接调用对象的方法。
多态性的例子:
def len(): return obj.len() len('123') len([1,2,3]) len({'a':1}) len((1,2,3))
# 鸭子类型 class People(): def speak(self): print('People') class Cat(): def speak(self): print('Cat') class Dog(): def speak(self): print('Dog') class Flower(): def f(self): print('Flower') obj = People() obj1 = Cat() obj2 = Dog() obj3 = Flower() # 定义一个功能用来执行共有的功能 def Animal(obj): return obj.speak() Animal(obj) #People Animal(obj1) #Cat Animal(obj2) #Dog Animal(obj3) # 没有speak这个功能所以会报错 AttributeError: 'Flower' object has no attribute 'speak'
强制限制(不推荐):
通过在父类导入 abc模块,将类抽象化,从而限制子类必须要有某些方法。抽象类的特点:只能被继承,不能被实例化。抽象类中的方法都是抽象方法,抽象方法不会实现具体的功能,只是用来限制子类的行为。
# 强制限制 import abc class Animal(metaclass=abc.ABCMeta): @abc.abstractmethod # 该装饰器限制子类必须定义有一个名为talk的方法 def speak(self): # 抽象方法中无需实现具体的功能 pass def eat(self): pass class cat(Animal): def speak(self): print('cat speak miao') def eat(self): print('cat eat fish') class pig(Animal): def sleep(self): print('pig always sleep') obj = cat() # 若子类pig中没有一个名为talk的方法则会抛出异常TypeError,无法实例化。 obj1 = pig() # TypeError: Can't instantiate abstract class pig with abstract methods speak obj.speak() # cat speak miao obj.eat() # cat eat fish # pig 类中没有speak方法,而在父类Animal中speak方法被抽象化了,所以子类中必须要定义speak方法 # obj1.sleep() # TypeError: Can't instantiate abstract class pig with abstract methods 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.x = obj1 # 组合,此时的obj就是一个超级对象,通过一个对象得到另外一个对象的值 print(obj.x.n) # obj.x 就是 obj1 结果为:20
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') # print(python.course_name) # python class Student(People): def __init__(self, name, age, gender, course=None): if course is None: course = [] super().__init__( name, age, gender) # 调用People里的__init__ self.courses = course def choose_course(self): pass stu = Student('kevin', '19', 'male') stu.courses.append(python) # stu.courses ====> [python对象] stu.courses.append(linux) # stu.courses ====> [python对象, linux对象] print(stu.courses) # [<__main__.Course object at 0x00000149EE630940>, <__main__.Course object at 0x00000149EE630A20>] for i in stu.courses: print(i.course_name) print(i.course_price) # 结果为: # python # 10000 # linux # 20000
标签:obj,继承,多态性,self,多态,查找,print,class,def From: https://www.cnblogs.com/Lucky-Hua/p/17508920.html