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中,经典类遵循“深度优先搜索” 。