9.继承、多继承、魔术方法
本次课及以后会用到Pycharm,仍能连接虚拟机。
1.继承
子类(新类)继承父类(已存在的类),子类拥有父类的所有问题,并可以拥有自己的新功能
语法:class 子类名(父类名): 例:clas Father(object): #和class Father:等价
属性 def __init__(self, name):
方法 self.name=name
调用:实例=子类名 def eat():
顶级基类 object print(self, "在吃东西")
object是所有类的父类 class Son:
若子类无直接父类,则寻找父类 pass
的父类,直到找到其父类 son = Son('sakura')
__bases__ 输出类直接父类的元组 son.eat() #sakura在吃东西
用法:类名.__bases__(不能用实例名)
例:print(son.__bases__) #<class '_main_.Father'>
2.多继承
一个类可以有多个父类
语法:class 子类名(父类1,父类2,...)
重写
1)若父类中有相同的方法,则按照参数列表的先后顺序调用
2)子类若不想用父类的方法,可通过重写来覆盖,即写和父类方法名相同的方法
3)重写后仍想调用父类的方法,则通过 类名. 方法名(实例)/super().方法名 来实现(1)的规则 仍适用)
例:
class base: def __init__(self): print('base init') def play(self): print('这是base') class A(base): def __init__(self): super(A,self).__init__() print('A init') def play(self): super().play() print('这是A') a = A() print(a.play())
base init A init 这是base 这是A None
__mro__属性 查看类的所有父类(直接和非直接),返回一个元组
mro()方法 查看所有父类(直接和非直接),返回列表
3魔术方法
所有以"__"双下划线包起来的方法,都统称为"魔术方法"。如用过的__init__,__del__
常用魔术方法
1) 运算符方法(了解一下,实际应用并不多)
__add__(self,other) # x+y
__sub__(self,other) # x-y
__mul__(self,other) # x*y
__mod__(self,other) # x%y
__iadd__(self,other) # x+=y
__isub__(self,other) # x-=y
__radd__(self,other) # y+x
__rsub__(self,other) # y-x
__imul__(self,other) # x*=y
__imod__(self,other) # x%=y
例:class Rectangle:
def __init__(self, length, width):
self.length=length
self.width=width
def area(self):
areas=self.length*self.width
def __add__(self, other): #other可以认为是另一个类
add_length=self.length+other.length
add_width=self.width+other.width
return add_length,add_width
a = Rectangle(3, 4)
b = Rectangle(5, 6)
print(a+b)
2)__str__和__repr__
在交互模式下输出的交互信息与直接print的信息有所不同,便依赖于__str__,__repr__
print打印对象调用__str__方法,若没有,则调用__repr__方法
在交互模式下,直接输出对象名,显示__repr__的返回值,与__str__无关
例:
class Rectangle:
def __init__(self,length,width):self.length = length
self.width = width
def area(self):
areas = self.length * self.width
return areas
def __str__(self):
return 'length is %s, width is %s '%(self.length, self.width)
def __repr__(self):
return 'area is %s'%self.area()
a = Rectangle(4, 5)
print(a) #length is 4, width is 5,若不存在__str__方法,则输出area is 20
a #交互模式下直接变量名a后回车,输出area is 20
对使用者友好的是__str__方法,对开发者调试友好的是__repr__方法
如何抉择:
str 尽可能的提供简洁且有用的信息,让用户尽可能吸收到必要的信息。
repr 尽可能向开发者提供创建该对象时的必要信息,让开发者可以直接通过复制粘贴来重建对象。
3)__call__ 实例像函数一样被调用
函数定义为def 函数名():后接函数的方法,正常情况下,实例是不能像函数一样被调用,要想能被调用,就要定义__call__方法。
4)类的一些查询相关信息的方法(了解即可)
- __class__ 查看类名
- __dict__ 查看全部属性,返回属性和属性值键值对形式
- __doc__ 查看对象文档,即类中(用三个引号引起来的部分)
- __bases__ 查看父类
- __mro__ 查看多继承的情况下,子类调用父类方法时,搜索顺序
实例.__class__.__mro__