1. 程式人生 > >Python入門學習筆記————13(繼承,多型,類相關函式)

Python入門學習筆記————13(繼承,多型,類相關函式)

#父類

class A ():
    pass
class B (A):
    pass
print(A.__mro__)
print(B.__mro__)
(<class '__main__.A'>, <class 'object'>)
(<class '__main__.B'>, <class '__main__.A'>, <class 'object'>)

單繼承和多繼承

  • 單繼承:每個類只能繼承一個類
  • 多繼承:每個類允許繼承多個類

    單繼承和多繼承的優缺點

  • 單繼承:
    • 傳承有序邏輯清晰語法簡單隱患少
    • 功能不能無限擴充套件,只能在當前唯一繼承鏈中擴充套件
  • 多繼承:
    • 類的功能擴充套件方便
    • 繼承關係混亂

In [14]:

 

#多繼承例項
class Fish():
    def __init__(self,name):
        self.name=name
    def swim(self):
        print('swimming...')
class Bird ():
    def __init__(self,name):
        self.name = name
    def fly(self):
        print('flying...')
class Person ():
    def __init__(self,name):
        self.name = name
    def work(self):
        print('working...')
 
class Superman (Fish,Bird,Person):#有順序
    def __init__(self,name):
        self.name = name
 
s = Superman('goudan')
s.swim()
s.fly()
s.work()
#單繼承的例子
class Student(Person):
    def __init__(self,name):
        self.name = name
t = Student('pidan')
t.work()
swimming...
flying...
working...
working...

菱形繼承/鑽石繼承

  • 多個子類繼承自同一個父類,這些子類又被同一個類繼承,於是繼承關係圖形成一個菱形
  • 關於多繼承的MRO
    • MRO就是多繼承中用於儲存繼承順序的一個列表
    • Python本身採用c3演算法來對多繼承的菱形繼承進行計算結果
    • MRO列表的計算原則:
      • 子類永遠再父類前
      • 如果多個父類,則根據繼承語法中括號內類的書寫順序存放
      • 如果多個類繼承了同一個父類,孫子類中只會選取繼承語法括號中的第一個父類的父類

In [16]:

 

#菱形繼承問題
class A ():
    pass
class B (A):
    pass
class C (A):
    pass
class D (B,C):
    pass

建構函式

  • 在物件進行例項化的時候,系統自動呼叫的一個函式叫做建構函式,通常此函式用來對例項物件進行初始化

In [18]:

 

#建構函式例子
class Person ():
    #對Person類進行例項化的時候
    #姓名確定
    #年齡確定
    def __init__ (self):
        self.name = 'goudan'
        self.age = 18
        self.address = 'where'
        print ('hello word!')
p = Person()
hello word!

In [21]:

 

#對建構函式進行擴充套件
class A ():
    def __init__(self,name):
        print('A')
        print(name)
class B (A):
    def __init__(self,name):
        A.__init__(self,name) #呼叫父類的建構函式
        print('我是B')#增加自己的建構函式
b = B('hello') #結構需要相符
 
A
hello
我是B

多型

  • 多型就是同一個物件在不同的情況有不同的狀態
  • 多型不是語法,是一種設計思想
  • 多型性: 一種呼叫方式,不同執行效果
  • 多型: 同一事物的多種形態,動物分為人類,狗,等

    Mixin設計模式

  • 主要採用多繼承方式對類的功能進行擴充套件
  • 我們使用多繼承語法實現Mixin
  • 使用Mixin實現多繼承的時候要非常小心
    • 首先必須表示某一單一功能,而不是某個物品
    • 職責必須單一,如果有多個功能,則寫多個Mixin
    • Mixin不能依賴於子類的實現
    • 子類即使沒有繼承這個Mixin類,也能照樣工作,只是缺少了某各功能
  • 優點
    • 使用Mixin可以在不對類進行任何修改的情況下擴充功能
    • 可以方便的組織維護不同功能元件的劃分
    • 可以根據需要任意調整功能類的組合
    • 可以避免建立很多新的類,導致類的繼承混亂

In [39]:

 

#Mixin案例
class Person ():
    name = 'haha'
    age = 18
    def eat (self):
        print('eating')
    def sleep (self):
        print('sleeping')
class Student(Person):
    def study (self):
        print('studying')
class Teacher (Person):
    def work (self):
        print('working')
class Tutor(Teacher,Student):
    pass
t = Tutor()
print(Tutor.__mro__) #MRO列表  多繼承
print(t.__dict__)#例項
print(Tutor.__dict__)
print('*'*50)
class TeacherMixin ():
    def work (self):
        print('work')
class StudentMixin():
    def study (self):
        print('study')
class TutorM(Person,StudentMixin,TeacherMixin):
    pass
t = TutorM()
print(TutorM.__mro__) #MRO列表  多繼承
print(t.__dict__)#例項
print(TutorM.__dict__)
(<class '__main__.Tutor'>, <class '__main__.Teacher'>, <class '__main__.Student'>, <class '__main__.Person'>, <class 'object'>)
{}
{'__module__': '__main__', '__doc__': None}
**************************************************
(<class '__main__.TutorM'>, <class '__main__.Person'>, <class '__main__.StudentMixin'>, <class '__main__.TeacherMixin'>, <class 'object'>)
{}
{'__module__': '__main__', '__doc__': None}

類相關函式

  • issubclass:檢測一個類是否是另一個類的子類
  • isinstance:檢測一個物件是否是一個類的例項
  • hasattr:檢測一個物件是否有成員XXX
  • gettattr、setattr、delattr等用法相同
  • dir: 獲取物件成員列表

In [48]:

 

#issubclass
class A ():
    pass
class B (A):
    pass
class C ():
    pass
print(issubclass(B,A))
print(issubclass(C,A))
#isinstance
class A ():
    pass
a = A()
print(isinstance(a,A))
print(isinstance(A,A))
#hasattr
class A():
    name = 'Noname'
 
a = A()
print(hasattr(a,'name'))
print(hasattr(a,'age'))
True
False
True
False
True
False

In [51]:

 

#dir
class A ():
    pass
dir(A)

Out[51]:

['__class__',
 '__delattr__',
 '__dict__',
 '__dir__',
 '__doc__',
 '__eq__',
 '__format__',
 '__ge__',
 '__getattribute__',
 '__gt__',
 '__hash__',
 '__init__',
 '__init_subclass__',
 '__le__',
 '__lt__',
 '__module__',
 '__ne__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__setattr__',
 '__sizeof__',
 '__str__',
 '__subclasshook__',
 '__weakref__']