继承
一、继承 问题引入
1.两个中有大量重复的代码, 是否能够只写一次 ?
抽象出一个更抽象的类,放公共代码
2.继承的意义是什么 ?
重用代码,方便代码的管理和修改
3.继承是复制变量空间嘛 ?
只是引用,不会复制
二、分类关系图
三、从矩形类中派生正方形类
注:派生和继承是一个意思
class Rectangle(object): #长方形类 def __init__(self,length,width): self.length = length self.width = width def area(self): areas = self.length * self.width print(areas) class Square(Rectangle): #正方形类 pass a = Square(6,6) a.area() 36
四、调用父类 重写方法
当子类重写父类方法之后,子类如果想再次调用父类的方法,可以使用这两种方法
方式一: 父类名.方法名(self) 方式二: super.方法名()
注意:用类名调用的时候,( )里面要写self
class Rectangle(object): #长方形类 def __init__(self,length,width): self.length = length self.width = width def area(self): areas = self.length * self.width print(areas) class Square(Rectangle): #正方形类 def __init__(self,length,width): if length == # self.length = length # self.width = width Rectangle.__init__(self, length, width) print('初始化成功') else: print('传入长宽不等,不进行初始化') a = Square(6,6) a.area() 初始化成功 36
五、顶级基类 object
class Rectangle: #经典类 pass class Rectangle(object): #新式类 pass #Python 2.x中默认都是经典类,只有显式继承了object才是新式类 #Python 3.x中默认都是新式类,写不写object都一样,都继承object # __base__特殊属性 #__bass__:查看继承的父类 #Rectangle.__base__ #__bases__:查看继承的全部父类 #Rectangle.__bases__
class Rectangle(object): def __init__(self,length,width): self.length = length self.width = width def area(self): areas = self.length * self.width print(areas) class Square(Rectangle): pass print(Square.__bases__ ) print(Square.__base__ ) a = Square(6,6) a.area() (<class '__main__.Rectangle'>,) <class '__main__.Rectangle'> 36
多继承
一、多继承
通过C类实例的方法调用来看 当继承多个父类时,如果父类中有相同的方法, 那么子类会优先使用最先被继承的方法
class Base: pass def func(self): print('---------base---func---------') class A(Base): pass def func_a(self): print('---------a---funca------------') def func(self): print('---------a---func---------') class B(Base): pass def func_b(self): print('---------b---func_b------------') def func(self): print('---------b---func---------') class D(Base): pass def func_d(self): print('---------D---func_d------------') def func(self): print('---------D---func---------') class C(A,B,D): def func(self): print('---------c---func---------') super().func() c = C() c.func() ---------c---func--------- ---------a---func---------
二、多继承 调用父类重写方法
当子类重写父类方法之后,子类如果想再次调用父类的方法,可以使用这两种方法
使用 super调用父类重名方法,可以通过类的__mro__属性来查看多继承的 情况下,子类调用父类方法时,在父类中的搜索顺序
li = C.mro() for i in li: print(i) <class '__main__.C'> <class '__main__.A'> <class '__main__.B'> <class '__main__.D'> <class '__main__.Base'> <class 'object'>
在python3中,类被创建时会自动创建属性 __mro__ 解析顺序
类在生成时会自动生成方法解析顺序,可以通过 类名.mro()来查看
object是所有类的父类
三、基于多继承的 Mix-in 设计模式
魔术方法
__add__ :当类的实例之间使用+号时,会自动调用__add__这个魔法方法
一、魔术方法之运算方法
二、__str__ 和 __repr__
str和repr都是分别调用这两个魔术方法来实现的
调用str函数来处理实例对象,如果对象没有定义__str__方法,则调用__repr__方法。
调用repr函数来处理实例对象,则调用__repr__处理。
注:__str__和__repr__原理
在python中,__repr__和__str__这两个方法都是用于显示的,__str__是面向用户的,而 __repr__面向程序员。
使用内置函数str和repr方法在处理对象的时候,分别调用的是对象的__str__ 和__repr__方法
调用str函数来处理输出的对象,如果对象没有定义__str__方法,则调用__repr__方法 调用repr函数来处理输出的对象,则调用__repr__处理, 使用print操作 会首先尝试
调用__str__方法 ,如果__str__方法没有定义,则调用__repr__方法 在交互模式下,输入对象 显示对象 __repr__ 方法的返回值
1.只写了__str__魔术方法: 交互模式输入:a ,返回的是一个对象 print(a) : 打印__str__魔术方法,返回的内容
2.只写了__repr__魔术方法:
交互模式输入 a :返回的是调用__repr__魔术方法,返回的内容
print(a) : 打印调用__repr__魔术方法,返回的内容
3.__repr__魔术方法 和 __str__魔术方法 都 写上
交互模式输入a :返回的是调用__repr__魔术方法,返回的内容
print(a) : 打印调用__str__魔术方法,返回的内容
__str__ 与 __repr__ 该如何抉择
str:
尽可能的提供简洁且有用的信息。 让用户尽可能吸收到必要的信息。
repr:
尽可能向开发者提供创建该对象时的必要信息。 让开发者可以直接通过复制粘贴来重建对象。
三、__call__方法
正常情况下,实例是不能像函数一样被调用的,要想实例能够被调用,就需要 定义 __call__ 方法
四、类中的一些查询相关信息的方法 (了解既可)
1、__class__ 查看类名 格式: 实例.__class__
2、__dict__ 查看全部属性,返回属性和属性值键值对形式 格式:实例.__dict__
3、__doc__ 查看对象文档,即类中(用三个引号引起来的部分) 格式:类名.__dict__
4、__bases__ 查看父类 格式:类名.__base__
5.__mro__ 查看多继承的情况下,子类调用父类方法时,搜索顺序 格式:子类名.__mro__ 实例.__class__.__mro__