目录
一、新式类和经典类
经典类:python2中有继承类
新式类:python3中都是新式类
-
是一种新建类方式,继承了一个类,类中的属性和方法就在子类中
-
父类/基类
-
子类/派生类
-
新式类:只要继承了object类,在python3中,默认继承object类。
- python3中,默认继承继承object类
- python2中,需要显示的指定继承object
-
经典类:没有继承object的类,就是经典类
- python3中没有经典类,都是新式类
- python中有经典类
-
在python3中都是新式类
class A: # 新式类:默认继承object,相当于:class A(object) pass
-
在python2中
class A: #经典类,没有继承 pass
class A(object): # 相当于python3中的新式类 pass
1.1 继承
class A:
pass
class C(A): # C继承了A这个类
pass
class A:
pass
class B:
pass
class C(A,B): # C继承了A,B这俩个类
pass
1.2类中的其他属性
class A:
pass
class B:
pass
class C(A,B): # C继承了A,B这俩个类
pass
print(C.__bases__)#C的父类
print(C.__dict__)#C中的方法
print(C.__name__)#C的名字
#输出:
(<class '__main__.A'>, <class '__main__.B'>)
{'__module__': '__main__', '__doc__': None}
C
二、利用继承减少代码冗余
2.1 减少冗余
类实例化会自动调节__init__如果类中没有,就会去父类找
class Person(object):
school = 'oldboy'
def __init__(self,name,age):
self.name = name
self.age = age
class Teacher(Person):
pass
class Student(Person):
pass
stu = Student('crean',18)
print(stu.name)
2.2多层继承
class A:
h = "AAA"
class B(A):
h = "BBB"
class C(B):
h = "CCC"
class D(C):
# h = "DDD"
pass
d = D()
print(d.h)
#
CCC
class A:
h = "AAA"
class B:
h = "BBB"
class C:
h = "CCC"
class D(A,B,C):
# h = "DDD"
pass
d = D()
print(d.h)
#
AAA
三、继承的菱形问题
3.1菱形问题
class G(object):
a = "GGG"
pass
class F(G):
# a = "FFF"
pass
class E(G):
# a = "EEE"
pass
class D(G):
# a = "DDD"
pass
class C(F):
# a="CCC"
pass
class B(E):
# a="BBB"
pass
class A(B,C,D):
# a="AAAA"
pass
a = A()
print(a.a)
print(A.mro())
print(A.__mro__)
#
GGG
[<class '__main__.A'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.F'>, <class '__main__.D'>, <class '__main__.G'>, <class 'object'>]
(<class '__main__.A'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.F'>, <class '__main__.D'>, <class '__main__.G'>, <class 'object'>)
mro()列表,继承顺序查找列表(只在新式类中有)1
mro()和、__mro__是相等的
print(A.mro())
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'>]
(<class '__main__.A'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.F'>, <class '__main__.D'>, <class '__main__.G'>, <class 'object'>)
3.2对菱形问题的总结
- 继承的菱形问题(显示的都继承一个类,不是object类):新式类和经典类的查找顺序是不一样的
- 新式类(py3中全是新式类):广度优先---从左侧开始,一直往上找,找到菱形的顶点结束(不包括菱形顶点),继续下一个继承的父类往上找,找到菱形的顶点结束(不包括菱形顶点),最后找到菱形顶点
- 经典类(只有py2中才有):深度优先---从左侧开始,一直往上找,找到菱形的顶点结束(包括菱形顶点)继续下一个继承的父类往上找,找到菱形的顶点结束(不包含菱形定点)(经典类就是没有继承(object))
- 不出现菱形问题:正常查找
四、如何重用父亲的属性和方法
4.1 如何重用父亲的属性和方法一
继承重用父亲类方法1:指明道姓的使用,跟继承没有关系
class Person:
school = 'oldboy'
def __init__(self,name,age):
self.name = name
self.age = age
def study(self):
print("study....")
class Student(Person):
def __init__(self,name,age,course):
#重用父类的__init__方法
Person.__init__(self,name,age)
self.course = course
def study(self):
#重用父类的__init__方法
Person.study(self)
print("%s学生在学习"%self.name)
stu1 = Student('chen','18','python')
print(stu1.school)
stu1.study()
#
oldboy
study....
chen学生在学习
4.2如何重用父类的属性和方法二
继承重用父类方法二:通过super关键字,跟继承是有关系
class Person(object):
school = 'oldboy'
def __init__(self,name,age):
self.name = name
self.age = age
def study(self):
print('study...')
class Student(Person):
def __init__(self,name,age,course):
#super()会按照mro列表拿出父亲对象
#对象来调用绑定方法,不需要传递第一个参数(self)
super().__init__(name,age)
#在新式类中一般都是上面的写法
#在经典类(python2)中必须严格用另外一种方式写,如下:
#super(Student,self).__init__(name,age)这种方式也可以在python3种使用
self.course = course
def study(self):
super().study()
stu = Student('ocera',18,'python')
print(stu.school)
stu.study()
#
oldboy
study...
总结:
- super()相当于得到了一个特殊对象,第一个参数不需要传,调用绑定方法,会把自己传过去。
- 这么写:super(类名,对象) 在py3中为了兼容py2。
- 如果继承了多个父类,super是按照mro列表找,现在想指名道姓的用某个父类的某个方法,就需要指名道姓的使用
4.3属性的查找顺序
先找对象---->到类中寻找------>父类中找(多继承)-------->都找不到进行报错