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

由此可以得出结论:经典类的搜索方式是采用“从左至右,深度优先”的方式去查找属性,如图:

总结

  1. 新式类继承object类,经典类没有继承object类(语法上的不同)
  2. 新式类使用super关键字继承构造方法,经典类使用父类.__init__(self)来继承构造方法(写法上的不同)
  3. 新式类查找属性时是广度优先搜索,经典类则是深度优先搜索(调用顺序上的不同)
  4. 注意:在Python 3中,无论是新式类还是经典类都遵循"广度优先搜索",而在Python 2中,经典类遵循“深度优先搜索” 。
posted @ 2017-08-13 20:24  Mr.hu  阅读(181)  评论(0编辑  收藏  举报