Python入門學習筆記————13(繼承,多型,類相關函式)
阿新 • • 發佈:2018-12-30
#父類
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__']