- 继承
- 继承解决代码冗余
- 子类重写OR复用父类的方法
- 子类重写OR复用父类的方法二
- 单继承
- 单继承的属性和方法的查找
- 多继承的属性和方法查找
- 常用的魔法方法
- __str__
- __del__
- __call__
1 什么是继承
继承一种新建类的方式,新建的类称之为子类/派生类,被继承的类称之为父类基类超类
python中继承的特点:
1. 子类可以遗传/重用父类的属性 或者方法
2 为何要用继承
减少类与类之间代码冗余
3 如何用继承class Parent(父类): pass
class Parent():
xxx = 333
def run(self):
print('我是父类的方法')
class Sub(Parent):
# xxx= 222
pass
obj=Sub()
# ,属性查找的优先级
# obj.xxx= 111
# 子类有属性就用子类的,没有就访问父类的
print(obj.xxx)
obj.run()
继承解决代码冗余
'''
总结对象的相似之处得到了类 *****
总结类的相似之处得到父类 *****
'''
class People:
school = '家里蹲'
def __init__(self,name,age,sex):
self.name = name
self.age = age
self.sex = sex
class Student(People):
def play(self):
print('%s play football'%self.name)
class Teacher(People):
def course(self):
print('%s course'%self.name)
s1=Student('小周',38,'male')
print(s1.__dict__)
t1=Teacher('小王',18,'male')
print(t1.__dict__)
# 但是这里有个问题子类有新的属性需要实例化的时候参数怎么办?
子类重写OR复用父类的方法
子类重用父类的功能
在子类派生出的新方法中重用父类功能的方式一:
指名道姓地引用某一个类中的函数
总结:
- 与继承无关
- 访问是类的函数,没有自动传值的效果
class People:
school = '家里蹲'
def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex
class Student():
def __init__(self,name,age,sex,score=0):
# 相当于调用了父类的方法
# 指名道姓People
People.__init__(self, name, age, sex)
self.score = score
def play(self):
print('%s play football' % self.name)
class Teacher():
def __init__(self,name,age,sex,hobby):
People.__init__(self, name, age, sex)
self.hobby = hobby
def course(self):
print('%s course' % self.name)
s1 = Student('小周', 38, 'male',99)
print(s1.__dict__)
t1 = Teacher('小王', 18, 'male','song')
print(t1.__dict__)
子类重写OR复用父类的方法二
单继承派生实例化除了父类的属性添加,还能有自己独有的属性 ******
在子类派生出的新方法中重用父类功能的方式二:super()必须在类中用
super(自己的类名,自己的对象)
可以省略传值
super()
# 单继承下的super()
class People:
school = '家里蹲'
def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex
class Student(People):
def __init__(self, name, age, sex, score=0):
# 相当于调用了父类的方法
# 指名道姓People
# People.__init__(self, name, age, sex)
# 必须要继承 Student父类的
# super(Student,self).__init__(name, age, sex)
# 可以省略传值
super().__init__(name, age, sex)
self.score = score
def play(self):
print('%s play football' % self.name)
class Teacher():
def __init__(self, name, age, sex, hobby):
People.__init__(self, name, age, sex)
self.hobby = hobby
def course(self):
print('%s course' % self.name)
s1 = Student('小王', 38, 'male', 99)
print(s1.__dict__)
t1 = Teacher('小周', 18, 'male', 'song')
print(t1.__dict__)
# 多继承super()
# 广度优先
class A:
def f1(self):
print('A.f1')
# super是照着mro列表c3算法来的
# # 不是按照当前继承的类来的
super().f2()
class B:
def f2(self):
print('B.f2')
class C(A,B):
def f2(self):
print('C.f2')
obj=C()
obj.f1()
print(C.mro())
单继承的属性和方法的查找
在单继承背景下属性和方法的查找优先级:对象->对象的类->父类->父类…->object
class Foo():
xxx = 444
pass
class Bar1(Foo):
xxx = 333
pass
class Bar2(Bar1):
xxx = 222
pass
obj = Bar2()
# obj.xxx = 111
print(obj.xxx)
class Foo:
def f1(self):
print('Foo.f1')
def f2(self):
print('Foo.f2')
self.f1()
# obj.f1()是Bar()的对象
class Bar(Foo):
def f1(self):
print('Bar.f1')
obj = Bar()
obj.f1()
# Foo.f2
多继承的属性和方法查找
在多继承背景下属性的查找优先级:
此时属性的查找优先级是:对象->对象的类->按照从左往右的顺序一个分支一个分支的找下去
广度优先查找,从左往右一个分支一个分支的查找,在最后一个分支才去查找顶级类
第四层
顶级类是在最后一个分之才走的
class G():
x = 'G'
pass
# 第三层
class E(G):
# x = 'E'
pass
class F(G):
# x='F'
pass
# 第二层
class B(E):
# x= "B"
pass
class C(F):
# x='C'
pass
class D(G):
# x='D'
pass
# 第一层
class A(B, C, D):
# x = 'A'
pass
obj = A()
# obj.x =111
print(obj.x)
# python专门为继承类内置了一个mro的方法,用来查看c3算法的计算结果
print(A.mro())
常用的魔法方法
str
# __str__: 在对象被打印时自动触发,可以用来定义对象被打印时的输出信息 ***
class People:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return ''%(self.name,self.age)
obj = People('小王',18)
print(obj)
del
# __del__ 在对象被删除时先自动触发该方法,可以用来回收对象以外其他相关资源,比如系统资源 **
class Foo:
def __init__(self, x, filepath, encoding='utf-8'):
self.x = x
self.f = open(filepath, 'rt', encoding=encoding)
def __del__(self):
# 回收对象关联的其他资源
print('123')
self.f.close()
obj = Foo(1, 'a.txt')
# 会调用对象的__del__方法,所以可以在__del__方法里面释放一些资源
del obj
call
# __call__: 在对象被调用时会自动触发该方法 *****
class Foo:
def __init__(self, name, age):
self.name = name
self.age = age
def __call__(self, *args, **kwargs):
print(self,args,kwargs)
obj=Foo(1,2)
obj()
obj(1,2,a=3,b=4)
# obj.__call__(obj,1,2,a=3,b=4)



