day6-新式类VS经典类
概述
Python除了前面的单继承外,还可以支持多继承,但是如果子类调用一个自身没有定义的属性,它是按照何种顺序去到父类寻找呢,尤其是众多父类中有多个都包含该同名属性。对经典类和新式类来说,属性的查找顺序是不同的。现在我们分别看一下经典类和新式类两种不同的表现。
类的多继承
class SchoolMember(object):
"""学校成员基类"""
member = 0
def __init__(self,name,age,sex):
self.name = name
self.age = age
self.sex = sex
self.enroll()
def enroll(self):
"""注册"""
print("just enrolled a new school member [%s]" %self.name)
SchoolMember.member +=1
def tell(self):
print("------%s-------"%self.name)
for k,v in self.__dict__.items():
print("\t",k,v)
print("===end===")
def __del__(self):
print("开除了[%s]..."%self.name)
SchoolMember.member -=1
class School(object):
"""学校类"""
def open_branch(self,addr):
print("Openning a new branch in",addr)
class Teacher(SchoolMember,School): #类的多继承
"""讲师类"""
def __init__(self,name,age,sex,salary,course):
# SchoolMember.__init__(self,name,age,sex) #经典类写法
super(Teacher, self).__init__(name,age,sex) #新式类写法
self.salary = salary
self.course = course
def teaching(self):
print("Teacher [%s] is teaching [%s]"%(self.name,self.course))
class Student(SchoolMember):
def __init__(self,name,age,sex,course,tuition):
SchoolMember.__init__(self,name,age,sex)
self.course = course
self.tuition = tuition
self.amount = 0
def paytuition(self,amount):
print("student [%s] has just paied [%s]"%(self.name,amount))
self.amount +=amount
t1 = Teacher("Dick",28,"M",3000,"Python")
s1 = Student("Sophie",25,"F","SAP",18000)
s2 = Student("Jacky",25,"M","SAP",15000)
print(SchoolMember.member)
t1.tell() #拥有父类SchoolMMember的tell方法
t1.open_branch("NJ") #拥有父类School的open_branch方法
s2.tell()
del s2
print(SchoolMember.member)
#输出
just enrolled a new school member [Dick]
just enrolled a new school member [Sophie]
just enrolled a new school member [Jacky]
3
------Dick-------
age 28
salary 3000
sex M
name Dick
course Python
===end===
Openning a new branch in NJ
------Jacky-------
age 25
tuition 15000
sex M
name Jacky
amount 0
course SAP
===end===
开除了[Jacky]...
2
开除了[Dick]...
开除了[Sophie]...
新式类VS经典类区别
新式类
定义:新式类是指继承object的类
class Person(object): #继承object类
........
继承构造方法
super(子类, self).__init__(name,age,sex) #新式类写法
调用父类中相同方法或相同属性的顺序
通过实验来说明:
class A(object):
def __init__(self):
self.n = "A"
class B(A):
def __init__(self):
self.n = "B"
class C(A):
def __init__(self):
self.n = "C"
class D(B,C):
def __init__(self):
self.n = "D"
d = D()
print(d.n)
#输出
D
首先,我们将D注释掉:
class D(B,C):
pass
#输出
B
接着,再将B注释掉:
class B(A):
pass
#输出
C
最后,再将C注释掉:
class C(A):
pass
#输出
A
解析:实例d调用D()时,搜索顺序是D=>B=>C=>A
由此可以得出结论:新式类的搜索方式是采用“广度优先”的方式去查找属性,如图:

经典类
定义:经典类是指没有继承object的类
class Person:
........
继承构造方法
父类__init__(self,name,age,sex) #经典类写法
调用父类中相同方法或者相同属性的顺序
通过实验来说明:
class A:
def __init__(self):
self.n = "A"
class B(A):
def __init__(self):
self.n = "B"
class C(A):
def __init__(self):
self.n = "C"
class D(B,C):
def __init__(self):
self.n = "D"
d = D()
print d.n
#输出
D
首先,我们将D注释掉:
class D(B,C):
pass
# def __init__(self):
# self.n = "D"
#输出
B
接着,再将B注释掉:
class B(A):
pass
# def __init__(self):
# self.n = "B"
#输出
A
最后,再将A注释掉:
class A:
pass
# def __init__(self):
# self.n = "A"
#输出
C
解析:实例d调用D()时,搜索顺序是D=>B=>A=>C
由此可以得出结论:经典类的搜索方式是采用“从左至右,深度优先”的方式去查找属性,如图:

总结
- 新式类继承object类,经典类没有继承object类(语法上的不同)
- 新式类使用super关键字继承构造方法,经典类使用父类.__init__(self)来继承构造方法(写法上的不同)
- 新式类查找属性时是广度优先搜索,经典类则是深度优先搜索(调用顺序上的不同)
- 注意:在Python 3中,无论是新式类还是经典类都遵循"广度优先搜索",而在Python 2中,经典类遵循“深度优先搜索” 。

浙公网安备 33010602011771号