1. 程式人生 > >4月12日 python學習總結 繼承和派生

4月12日 python學習總結 繼承和派生

__name__ sch 繼承和派生 utf-8 代碼冗余 空間 校驗 oldboy 示例

一、繼承

  1.  什麽是繼承:

       繼承是一種新建類的方式,在python中支持一個子類繼承多個父類

       新建類稱為子類或派生類

       父類可以稱之為基類或者超類

       子類會遺傳父類的屬性

2.   為什麽繼承

      減少代碼冗余

  3.  定義方式:

class Parent:
    pass
class SubClass(Parent):
    pass

print(SubClass.__bases__)   #查看類的父類

4.  繼承,調用父類方法以及self

class Foo:
    def f1(self):
        
print(Foo.f1) def f2(self): #self=obj print(Foo.f2) self.f1() #obj.f1() class Bar(Foo): def f1(self): print(Bar.f1) obj=Bar() # print(obj.__dict__) obj.f2() #輸出為: FOO.f1 # Bar.f1

  

二、 派生

    子類定義自己新的屬性,如果與父類同名,以子類自己的為準

    在子類派生出的新方法中重用父類功能(最好不要兩種方法混著用):

    1. 指名道姓的調用(與繼承沒什麽關系)

class OldboyPeople:
    school = oldboy

    def __init__(self, name, age, sex):
        self.name = name
        self.age = age
        self.sex = sex

    def tell_info(self):
        print("""
        ===========個人信息==========
        姓名:%s
        年齡:%s
        性別:%s
        
""" %(self.name,self.age,self.sex)) class OldboyTeacher(OldboyPeople): def __init__(self, name, age, sex, level, salary): # self.name = name # self.age = age # self.sex = sex OldboyPeople.__init__(self,name, age, sex) #此處直接調用父類方法 self.level = level self.salary = salary def tell_info(self): OldboyPeople.tell_info(self) print(""" 等級:%s 薪資:%s """ %(self.level,self.salary))

  2. super()調用(嚴格依賴於繼承)

        super()的返回值是一個特殊的對象,該對象專門用來調用父類中的屬性

class OldboyTeacher(OldboyPeople):
    #            tea1,‘egon‘, 18, ‘male‘, 9, 3.1
    def __init__(self, name, age, sex, level, salary):
        OldboyPeople.__init__(self,name, age, sex)     #調用父類方法
        # super(OldboyTeacher,self).__init__(name,age,sex)  在python2中調用時用這種寫法

        self.level = level
        self.salary = salary

    def tell_info(self):
        # OldboyPeople.tell_info(self)
        super().tell_info()
        print("""
        等級:%s
        薪資:%s
        """ %(self.level,self.salary))

super()嚴格依賴繼承    

三、新式類與經典類

1、新式類

繼承object的類,以及該類的子類,都是新式類

在python3中,如果一個類沒有指定繼承的父類,默認就繼承object
所以說python3中所有的類都是新式類

2、經典類 (只有在python2才區分經典類與新式類):

沒有繼承object的類,以及該類的子類,都是經典類   

區別: 在菱形繼承的背景下,經典類和新式類才有區別。非菱形繼承時,是一樣的。但是當菱形繼承時,新式類會采用廣度優先,經典類深度優先

深度優先:按照從左往右的順序,每一條分支走到底,再轉入下一條分支

廣度優先:按照從左往右的順序,忽略菱形最頂上的父類,將除該父類之外的所有類進行深度優先遍歷,最後再查找該父類

   多繼承的類便利順序:一個對象繼承多個類,按照定義順序,從左到右,深度便利

   

技術分享圖片

      經典類遍歷結果:ABEGCFD

       新式類便利結果:ABECFDG 

#coding:utf-8
#在菱形繼承的背景下,查找屬性
#1、經典類:深度優先
#2、新式類:廣度優先


class A:
    # def test(self):
    #     print(‘from A‘)
    pass

class B(A):
    # def test(self):
    #     print(‘from B‘)
    pass

class C(A):
    # def test(self):
    #     print(‘from C‘)
    pass
class D(B):
    # def test(self):
    #     print(‘from D‘)
    pass

class E(C):
    # def test(self):
    #     print(‘from E‘)
    pass

class F(D,E):
    # def test(self):
    #     print(‘from F‘)
    pass
# f1=F()
# f1.test()

print(F.mro())

# F->D->B->E->C-A->object

  super()嚴格依賴繼承

#super()會嚴格按照mro列表從當前查找到的位置繼續往後查找
class A:
    def test(self):
        print(A.test)
        super().f1()
class B:
    def f1(self):
        print(from B)
class C(A,B):
    pass

c=C()
print(C.mro()) #C->A->B->object


c.test()

      

作 業 :

4月12日作業
    1、類的屬性和對象的屬性有什麽區別?
        類的屬性是所有對象共享的,對象的屬性,是對象單獨使用的
    2、面向過程編程與面向對象編程的區別與應用場景?
        1、面向過程是流水線式編程,先做什麽在做什麽
        2、面向對象是上帝視角的,面向一個個對象,讓對象之間交互解決問題
    3、類和對象在內存中是如何保存的。
        都是一串數據
        類在定義時,執行代碼,開辟內存空間,存放各種屬性名和方法名,但不執行__init__方法
        對象在執行是,調用類的__init__方法,開辟內存空間,存放該對象自己獨有的屬性名
    4、什麽是綁定到對象的方法,、如何定義,如何調用,給誰用?有什麽特性
        類的方法
        類的方法是綁定給對象用的,一個類的每一個對象,對應相同的類方法,在調用時相互獨立,互不相幹
    5、如下示例, 請用面向對象的形式優化以下代碼
       在沒有學習類這個概念時,數據與功能是分離的,如下
       def exc1(host,port,db,charset):
           conn=connect(host,port,db,charset)
           conn.execute(sql)
           return xxx
       def exc2(host,port,db,charset,proc_name)
           conn=connect(host,port,db,charset)
           conn.call_proc(sql)
           return xxx
       # 每次調用都需要重復傳入一堆參數
       exc1(127.0.0.1,3306,db1,utf8,select * from tb1;)
       exc2(127.0.0.1,3306,db1,utf8,存儲過程的名字)

       class exc:
            def __int__(self,host,port,db,charset,proc_name):
                self.host=host
                self.port=port
                self.db=db
                self.charset=charset
                self.proc_name = proc_name
                
            def exc1(self):
                conn = connect(self.host, self.port, self.db, self.charset)
                conn.execute(sql)
                return xxx

            def exc2(self):
                conn = connect(self.host, self.port, self.db, self.charset)
                conn.call_proc(sql)
                return xxx
       
    6、下面這段代碼的輸出結果將是什麽?請解釋。
        class Parent(object):
           x = 1

        class Child1(Parent):
           pass

        class Child2(Parent):
           pass

        print(Parent.x, Child1.x, Child2.x)   # 1 1 1
        Child1.x = 2
        print(Parent.x, Child1.x, Child2.x)   # 1 2 1
        Parent.x = 3
        print(Parent.x, Child1.x, Child2.x)      # 3 2 3

    7、多重繼承的執行順序,請解答以下輸出結果是什麽?並解釋。

        class A(object):
           def __init__(self):
               print(A)
               super(A, self).__init__()

        class B(object):
           def __init__(self):
               print(B)
               super(B, self).__init__()

        class C(A):
           def __init__(self):
               print(C)
               super(C, self).__init__()

        class D(A):
           def __init__(self):
               print(D)
               super(D, self).__init__()

        class E(B, C):
           def __init__(self):
               print(E)
               super(E, self).__init__()

        class F(C, B, D):
           def __init__(self):
               print(F)
               super(F, self).__init__()

        class G(D, B):
           def __init__(self):
               print(G)
               super(G, self).__init__()

        if __name__ == __main__:
           g = G()   #  G   D    A    B
           f = F()     #    F    C    B    D    A

    8、什麽是新式類,什麽是經典類,二者有什麽區別?什麽是深度優先,什麽是廣度優先?
        新式類:繼承自object,其子類也是新式類
        經典類:沒有繼承自object的所有類,其子類也是經典類
        區別: 非菱形繼承時,是一樣的。但是當菱形繼承時,新式類會采用廣度優先,經典類深度優先
        深度優先:按照從左往右的順序,每一條分支走到底,再轉入下一條分支
        廣度優先:按照從左往右的順序,忽略菱形最頂上的父類,將除該父類之外的所有類進行深度優先遍歷,最後再查找該父類
        
    
    9、用面向對象的形式編寫一個老師類, 老師有特征:編號、姓名、性別、年齡、等級、工資,老師類中有功能
        1、生成老師唯一編號的功能,可以用hashlib對當前時間加上老師的所有信息進行校驗得到一個hash值來作為老師的編號
            def create_id(self):
                pass
                
        2、獲取老師所有信息
            def tell_info(self):
                pass

        3、將老師對象序列化保存到文件裏,文件名即老師的編號,提示功能如下
            def save(self):
                with open(老師的編號,wb) as f:
                    pickle.dump(self,f)

        4、從文件夾中取出存儲老師對象的文件,然後反序列化出老師對象,提示功能如下
            def get_obj_by_id(self,id):
                return pickle.load(open(id,rb))

        答案:        
            import  hashlib
            import  datetime
            import  pickle
            class Teacher:
                def create_id(self):
                    m=hashlib.md5()
                    m.update(self.name.encode(gbk))
                    m.update(self.sex.encode(gbk))
                    m.update(bytes(self.age))
                    m.update(bytes(self.level))
                    m.update(bytes(self.salary))
                    m.update(str(datetime.datetime.now()).encode(gbk))
                    return m.hexdigest()

                def __init__(self,name,sex,age,level,salary):
                    self.name=name
                    self.age=age
                    self.sex=sex
                    self.level=level
                    self.salary=salary
                    self.id=self.create_id()

                def tell_info(self):
                     print(self.__dict__)

                def save(self):
                    with open(r%s.json%self.id, wb) as f:
                        pickle.dump(self, f)

                def get_obj_by_id(self):
                    with open(r%s.json % self.id, rb) as f:
                        info= pickle.load(f).__dict__
                        return info

            t=Teacher(egon,male,18,9,1.3)
            print(t.__dict__)
            t.save()
            print(t.get_obj_by_id())


    10、按照定義老師的方式,再定義一個學生類
            import  hashlib
            import  datetime
            import  pickle
            class Student:
                def create_id(self):
                    m=hashlib.md5()
                    m.update(self.name.encode(gbk))
                    m.update(self.sex.encode(gbk))
                    m.update(bytes(self.age))
                    m.update(str(datetime.datetime.now()).encode(gbk))
                    return m.hexdigest()

                def __init__(self,name,sex,age):
                    self.name=name
                    self.age=age
                    self.sex=sex
                    self.id=self.create_id()

                def tell_info(self):
                     print(self.__dict__)

                def save(self):
                    with open(r%s.json%self.id, wb) as f:
                        pickle.dump(self, f)

                def get_obj_by_id(self):
                    with open(r%s.json % self.id, rb) as f:
                        info= pickle.load(f).__dict__
                        return info

            s=Student(egon,male,18)
            print(s.__dict__)
            s.save()
            print(s.get_obj_by_id())
                
    
    
    11、抽象老師類與學生類得到父類,用繼承的方式減少代碼冗余
            import  hashlib
            import  datetime
            import  pickle
            class ParentClass:
                def create_id(self):
                    m=hashlib.md5()
                    m.update(self.name.encode(gbk))
                    m.update(self.sex.encode(gbk))
                    m.update(bytes(self.age))
                    m.update(str(datetime.datetime.now()).encode(gbk))
                    return m.hexdigest()

                def __init__(self,name,sex,age):
                    self.name=name
                    self.age=age
                    self.sex=sex
                    self.id=self.create_id()

                def tell_info(self):
                     print(self.__dict__)

                def save(self):
                    with open(r%s.json%self.id, wb) as f:
                        pickle.dump(self, f)

                def get_obj_by_id(self):
                    with open(r%s.json % self.id, rb) as f:
                        info= pickle.load(f).__dict__
                        return info
                
            class Teacher(ParentClass):
                def create_id(self):
                    m = hashlib.md5()
                    m.update(self.name.encode(gbk))
                    m.update(self.sex.encode(gbk))
                    m.update(bytes(self.age))
                    m.update(bytes(self.level))
                    m.update(bytes(self.salary))
                    m.update(str(datetime.datetime.now()).encode(gbk))
                    return m.hexdigest()
                def __init__(self, name, sex, age, level, salary):
                    self.level = level
                    self.salary = salary
                    super().__init__(name, sex, age)
                    self.id = self.create_id()    
    
            class  Student(ParentClass):
                def learn(self):
                    print(learning...)
 
    

    12、基於面向對象設計一個對戰遊戲並使用繼承優化代碼,參考博客
        http://www.cnblogs.com/linhaifeng/articles/7340497.html#_label1

    

 

4月12日 python學習總結 繼承和派生