Python:封裝、多型、多繼承、函式重寫、布林測試函式重寫、迭代器(高階)
阿新 • • 發佈:2018-12-19
用於類的函式:
issubclass(cls,class_or_tuple)判斷一個類是否繼承自某個類class或某類tuple中的
一個類,如果是則返回true,否則返回false
示例:
class A:
pass
class B(A):
pass
class C(B):
pass
issubclass(C,B) #TRUE
issubclass(bool) #TRUE
封裝
封裝是指隱藏類的實現細節,讓使用者不關心這些細節 封裝的目的是讓使用者通過儘可能少的方法(或屬性)操作物件私有屬性和方法 python類中以雙下劃線__開頭,不以雙下劃線結尾的識別符號為私有成員,私有成員只能使用該類的方法進行訪問和修改
class A:
def __init__(self):
self.__ppp=100 #建立私有屬性
self.ppp=200 #非私有屬性
def __m(self):
print('私有方法')
def test(self):
print('__ppp屬性的值為',self.__ppp)
self.__m() #可以呼叫__m
a=A()
print(a.__ppp)#出錯,不允許訪問私有屬性
print(a.ppp)#200
a.test()
多型 polymorphic
字面意思:多種狀態 程式語言的狀態: 靜態(編譯時的狀態) #c/c++ 動態(執行時的狀態) #c++/java 多型原指在有繼承關係的類中,呼叫基類物件的方法,實際能呼叫到子類覆蓋方法的現象叫多型 說明: python全部都得物件都只有“執行狀態(多型)”沒有c++語言裡的編譯時狀態(靜態)
class shape:
def draw(self):
print('shape.draw被呼叫')
class point(shape):
def draw(self):
print('point.draw被呼叫')
class circle(point):
def draw(self):
print('circle.draw被呼叫')
def mydraw(s):
s.draw #此處會根據s繫結物件的型別來決定呼叫誰
s1=circle()
s2=point()
mydraw(s2)
mydraw(s1)
面向物件程式語言的特徵:
繼承
封裝
多型
多繼承 multiple inheritance
多繼承是指一個類繼承自兩個或2個以上的基類
多繼承的語法:
class類名(基類名1,基類名2.....)
語句
說明:
1.一個子類同時繼承自多個父類,父類中的方法可以同時被繼承下來
2.如果兩個父類中有同名的方法,而在子類中又沒有覆蓋此方法時,呼叫結果難以確定
示例:
class car:
def run(self,speed):
print('汽車以',speed,'km/h的速度行駛')
class plane:
def fly(self,height):
print('飛機以海拔',height,'米的高度飛行')
class plane_car(car,plane):
'''plane_car類同時繼承2個類'''
p1=plane_car()
p1.fly(10000)
p1.run(300)
多繼承的問題(缺陷)
識別符號(名字空間)衝突的問題
要謹慎使用多繼承
示例:
class A:
def m(self):
print('A.m()被呼叫')
class B:
def m(self):
print('B.m()被呼叫')
class AB(A,B):
pass
ab=AB()
ab.m()
多繼承的MRO(Method Resolution Order)問題
MRO------>方法的解決(查詢)順序
類的__mro__屬性
用來記錄類的方法的查詢順序
class a:
def go(self):
print('a')
class b(a):
def go(self):
print('b')
class c(a):
def go(self):
print('c')
class d(b,c):
def go(self):
print('d')
d=d()
d.go
>>>d.__mro__
物件轉字串函式的使用:
repr(obj)返回一個附合Python語法規則的字串,
通常:
eval(repr(obj))==obj
str(obj)通過給定的物件返回一個字串(這個字串通常是給人閱讀的)
說明:以上兩個函式返回的是字串
s=input('請輸入')
s1=repr(s)
s2=str(s)
print('repr(s)',s1)
print('str(s)',s2)
函式重寫
函式重寫是指在自定義的類內新增相應的方法,讓自定義的類建立的例項可以像內建物件一樣進行函式操作
物件轉字串函式的重寫方法
repr(obj)函式的重寫方法:
def __repr__(self):
return'字串'
str(obj)函式的重寫方法:
def __str__(self):
return'字串'
s=input('請輸入')
s1=repr(s)
s2=str(s)
print('repr(s)',s1)
print('str(s)',s2)
str(obj)函式呼叫方法說明:
1.先呼叫obj.__str__()方法取值。
2.如果obj.__str__()方法不存在,則呼叫obj.__repr__()方法取值
3.如果再不存在obj.__repr__()方法.則呼叫object類的__repr__方法取值
內建函式重寫
方法名 函式名
__abs__(self) abs(obj)函式
__len__(self) len(obj)函式
__reversed__(self) reversed(obj)函式
__round__(self) round(obj)函式
class mylist:
'''自定義一個容器類mylist,內部採用列表來儲存內部的資料'''
def __init__(self,iterable=()):
self.date=[x for x in iterable]
def __len__(self):
'''此方法必須返回整數'''
return len(self.date)
myl=mylist([1,-2,3,-4])
print(len(myl))
數值轉換函式重寫
方法名 函式名
__complex__(self) complex(obj)
__int__(self) int(obj)
__float__(self) float(obj)
__bool__(self) bool(obj)
示例:
class mynumber:
def __init__(self,value):
self.date=value
def __int__(self):
return int(self.date)
def __float__(self):
return float(self.date)
n1=mynumber('100')
print(int(n1))#呼叫n1.__int__()
print(float(n1))#呼叫n1.__float__()
布林測試函式(bool)函式重寫
作用:
用於bool(obj)函式取值:
用於if語句的真值表達式
用於while語句的真值表達式中
說明:
1.優先呼叫obj.__bool__()方法進行取值
2.當不存在obj.__bool__()方法時,用obj.__len__()的返回值為零來測定布林值
當不存在__len__()方法時,則直接返回true
物件的屬性管理函式:
getattr(obj, name[, default]) 從一個物件得到物件的屬性;getattr(x, 'y') 等同於x.y; 當屬性不存在時,如果給
出default引數,則返回default,如果沒有給出default 則產生一個AttributeError錯誤
hasattr(obj, name) 用給定的name返回物件obj是否有此屬性,此種做法可以避免在getattr(obj, name)時引發錯誤
setattr(obj, name, value) 給物件obj的名為name的屬性設定相應的值value, set(x, 'y', v) 等同於 x.y = v
delattr(obj, name) 刪除物件obj中的name屬性, delattr(x, 'y') 等同於 del x.y
迭代器(高階)
什麼是迭代器
可以能過next(it)函式取值的物件就是迭代器
迭代器協議:
迭代器協議是指物件能夠使用next函式獲取下一項資料,在沒有下一項資料時觸發一個stopiteration異常來終止迭代的約定
迭代器協議的實現方法:
__next__(self)方法來實現迭代器協議
什麼是可迭代物件:
是指能用iter(obj)函式返回迭代器的物件(例項)
可迭代物件的內部要定義__iter__(self)方法來返回迭代器物件(例項)