文章目录
- 1.继承
- 1.1简述
- 1.2派生
- 1.3单/多继承
- 1.4.查看继承关系
- 2.提取父类
- 2.1实例
- 2.2查看继承
- 3.新式类/经典类
- 4.继承属性查找顺序
- 4.1单继承
- 4.2多继承查找
- 4.3菱形问题
- 4.3深度优先
- 4.4广度优先
- 5.Pyton Mixins机制
1.继承
1.1简述
ps:类是解决对象与对象之间的代码冗余.
继承:是解决类与类之间的代码冗余,将类中重复的代码提取出来将一个新的类(父类),
让需要使用和这个代码的类(子类)去继承父类.
1.2派生
派生:子类继承父类的属性,派生出自己都有的属性.
子类被称为派生类.
父类可以称为基类或超类.
父类中的数据,子类完全继承.
1.3单/多继承
单继承: 继承一个父类
多继承: 继承多个父类
1.4.查看继承关系
查看类继承了哪些类
类名.__base__ 查看单继承 , 看多继承只显示一个
类名.__bases__ 查看多继承 , 能看单继承
2.提取父类
提取类与类之间的相同数据,得出一个类,然后去继承这个类.
在类名后的括号内写上继承的名称. eg: 类名(继承谁就写谁的名字)
对象可以得到类的所有属性,子类可以继承父类的所有的属性.
子类中没有定义__init__方法, 但是会从父类中找__init__方法,找到变初始化数据.
2.1实例
# 学校类
class School:
school = 'XXX'
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
# 学生类
class Student(School):
pass
# 教师类
class Teacher(School):
pass
stu1 = Student('kid', 18, 'male')
tea1 = Teacher('xx', 30, 'male')
print(stu1.__dict__)
print(tea1.__dict__)
print(stu1.school)
print(tea1.school)
"""
{'name': 'kid', 'age': 18, 'gender': 'male'}
{'name': 'xx', 'age': 30, 'gender': 'male'}
XXX
XXX
"""
2.2查看继承
# 城市类
class City():
addr = 'xxx'
# 学校类
class School():
school = 'xxx'
identity = 'Student'
# 学生类
class Student(School, City):
pass
# 老师类
class Teacher(School, City):
pass
# 查看多继承
print(Student.__bases__) # (<class '__main__.School'>, <class '__main__.City'>)
print(Teacher.__bases__) # (<class '__main__.School'>, <class '__main__.City'>)
# 城市类
class City():
addr = 'xxx'
# 学校类
class School():
school = 'xxx'
identity = 'Student'
# 学生类
class Student(School, City):
pass
# 老师类
class Teacher(School):
pass
# __base__ 看多继承只能看一个 __bases__ 看单继承 只有一个
print(Student.__base__) # <class '__main__.School'>
print(Teacher.__bases__) # (<class '__main__.School'>,)
3.新式类/经典类
Python3 中:
新式类: 继承object类的子类, 以及该类的子类,子子类。
经典类: 没有继承 object类的子类, 以及该类的子类,子子类。
Python2 中:
不区分新式类与经典类.
Python 3 没有任何继承任何类,那么会默认继承object类, 所有都是新式类.
object类: Python内置的类, 存放了一些常用的功能.
# 城市类
class City():
addr = 'xxx'
# python 3.6 解释器
print(City.__base__) # <class 'object'>
* Python2 中没有.__base__
# *** coding=utf8 ***
# 城市类
class City():
addr = 'xxx'
# python 2.7 解释器
print(City.__bases__) # ()
4.继承属性查找顺序
4.1单继承
对象先从自己的.__dict__中查找,找不到,再去子类中查找,还没有去父类中找.父类中没有就去object中查找,都没有就会报错.
class A:
# def a(self):
# print('from A ---> a')
#
# def b(self):
# print('from A ---> b')
pass
class B(A):
# def a(self):
# print('from B ---> a')
#
# def b(self):
# print('from B ---> b')
pass
class C(B):
# def a(self):
# print('from C ---> a')
#
# def b(self):
# print('from C ---> b')
pass
class D(C):
pass
obj = D()
obj.a() # from A ---> a AttributeError: 'D' object has no attribute 'a' 报错
obj.b() # from A ---> b
4.2多继承查找
经典类:多继承情况下,会按照深度优先查找
新式类:多继承情况下,会按照广度优先查找
4.3菱形问题
一个类可以继承多个父类.
* 菱形问题
基类A 被父类B 与 父类C继承
子类继承 父类B 父类C
class A:
pass
class B(A):
pass
class C(A):
pass
class D(B, C):
pass
Python 解决方案:
每定义一个类,Python都会计算出一个所有基类的线性MRO列表,
继承的查找顺序按列表的顺序从左往右查找.
Python3中新式类 内置mro方法.
查询某个类的继承查找顺序,就以那个类为起点展开这个列表.
使用:
类名.__mor__
类名.mro()
Python2没有.mro() 方法
子类会优先父类被检测到(子子类>子类>父类>基类),多个父类会依据它们在列表中的顺序查找.
class A:
pass
class B(A):
pass
class C(A):
pass
class D(B, C):
pass
print(D.mro())
print(D.__mro__)
"""
[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>] 列表
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>) 元组
"""
4.3深度优先
经典类:按深度优先的方式查找,条分支找到底,
找完一条之后,再查另一条分支.
Python2 B(E) E(G) 分支直接查到G()
A(B, C, D) C(F) F(G) G() G()没有就放回其他分支...G()则不咋再查找
D(G)
# Python2
class G:
def text(self):
print 1
pass
class F(G):
def text(self):
print 2
pass
class E(G):
# def text(self):
# print 3
pass
class B(E):
# def text(self):
# print 4
pass
class C(F):
def text(self):
print 5
pass
class D(G):
def text(self):
print 6
pass
class A(B, C, D):
# def text(self):
# print 7
pass
obj = A()
obj.text()
4.4广度优先
新式类按广度优先方式查找.
广度优点按mro列表的顺序镜像查找.
检索第一条分支的之后不会访问到底,
之后在检索第二条分支,
当分支都被检测完之后,在查找所有分支的同一个基类.
Python3 B(E) E(G) 分支直接查到E()
A(B, C, D) C(F) F(G) G() E()没有就放回其他分支...
D(G) 最后在找G()
# python2.7下测试
class G():
# def test(self): # 4
# print('from G')
pass
class F(G):
# def test(self): # 3
# print('from F')
pass
class E(G):
# def test(self): # 2
# print('from E')
pass
class B(E):
# def test(self):
# print('from B') # 1
pass
class C(F):
# def test(self): # 5
# print('from C')
pass
class D(G):
def test(self): # 6
print('from D')
class A(B, C, D):
pass
obj = A()
obj.test()
# Python 3.8
print(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'>]
5.Pyton Mixins机制
多继承的正确打开方式:mixins机制
mixins机制核心:就是在多继承的背景下尽可能地提升多继承的可读性
Mixins机制机制指的是子类混合了不同类的属性和功能,而这些属性和功能统一命名规范。区分主类和辅类。
继承辅类的位置在主类的左边.(辅类1, 辅类2,主类)
辅类命名以Mixin,able,ible结尾。
主类只有一个,辅类可以有很多个.
主类中:
功能可以用很多个
辅类中:
一个辅类可能只有一个功能
# 交通工具
class Vehicle:
def run(self):
pass
# 飞行功能 辅类
class FlyMixin():
def fly(self):
'''
飞行功能相应的代码
'''
print("I am flying")
class CivilAircraft(FlyMixin, Vehicle): # 民航飞机
pass
class Helicopter(FlyMixin, Vehicle): # 直升飞机
pass
class Car(Vehicle): # 汽车并不会飞,如果不设置辅类,汽车也能飞了
pass