封裝enclosure
封裝是指隱藏類的實現(xiàn)細(xì)節(jié),讓使用者不關(guān)心這些細(xì)節(jié)
封裝的目的是讓使用者能過盡可能少的方法或?qū)傩圆僮鲗ο?/span>
python的封裝是模擬的封裝
私有屬性和方法:
python類中以雙下劃線'__' 開頭,不以雙下劃線結(jié)尾的標(biāo)識符為私有成員,私有成員只能使用方法進行訪問和修改
兩種:
私有屬性
私有方法--- 只能讓該類的方法來調(diào)用
class A:def __init__(self):self.__money =
0def show_money(self):print(
"self.__money = ",self.
__money)def make_money(self, m):self.__money +=
ma =
A()a.__money = 100
# 修改屬性print(a.
__money)
# 屬性取值a.show_money()
# 0a.make_money(999
)a.show_money() # 999 View Code 多態(tài) polymorphic:
字面意思是"多種狀態(tài)"
多態(tài)是指在有繼承/派生關(guān)系的類中,調(diào)用基類的對象的方法,實際能調(diào)用子類的覆蓋方法的現(xiàn)象叫多態(tài)
狀態(tài):
靜態(tài)(編譯時狀態(tài))
動態(tài)(運行時狀態(tài))
說明:
python全部對象都只有運行時狀態(tài),沒有編譯時狀態(tài)
class A:def do(self):print(
"A")class B(A):def do(self):print(
"B")class C(B):def do(self):print(
'C')def work(obj):obj.do() # 請問調(diào)用誰?
L =
[A(), B(), C(), B()]for x
in L:work(x) View Code 多繼承 multiple inheritance
多繼承是指一個子類繼承自兩個或兩個以上的基類
語法:
class 類名(基類名1, 基類名2, ....):
語句塊
說明:
一個子類同時繼承自多個父類,父類中的方法可以同時被繼承下來
如果兩個父類中有同名的方法,而在子類中又沒有覆蓋此方法時,調(diào)用結(jié)果難以確定
class Plane:def fly(self, height):print(
"飛機以海拔", height,
"米的高度飛行")class Car:def run(self, speed):print(
"汽車以", speed,
'km/h的速度行駛')class PlaneCar(Plane, Car):'''PlaneCar同時繼承自汽車類和飛機類'''pc =
PlaneCar()pc.run(300
)pc.fly(10000)
View Code 多繼承的問題(缺陷)
標(biāo)識符沖突的問題
要謹(jǐn)慎使用多繼承
# 小張寫了一個類A:class A:def m(self):print(
"A")# 小李寫了一個類Bclass B:def m(self):print(
"B")# 小王感覺小張和小李寫的類自己可以用class AB(A, B):passab =
AB()ab.m() # 調(diào)用誰由繼承列表中先后順序來決定 View Code 多繼承的問題MRO(method resolution order)問題
類的 __mro__屬性
用來記錄每個類的方法的查找順序
用MRO來確定鉆石繼承的方法查找順序
? A
? / \
B C
? \ /
? D
class A:def go(self):print(
"A")class B(A):def go(self):print(
"B")super().go() # Cclass C(A):def go(self):print(
"C")super().go() # Aclass D(B, C):def go(self):print(
'D')super().go()d =
D()d.go() # ??? View Code 面向?qū)ο缶幊陶Z言特征
封裝
繼承
多態(tài)
面向?qū)ο蟮木幊陶Z言:
C++, C#, Python, Java, objective-c, swift, ...
函數(shù)(方法)重寫
在自定義的類內(nèi)添加相應(yīng)的方法,讓自定義的類創(chuàng)建的實例像內(nèi)建對象一樣進行內(nèi)建函數(shù)操作
對象轉(zhuǎn)字符串函數(shù)的重寫(覆蓋)
repr(obj) 返回一個符合Python語法規(guī)則的字符串:
通常:
eval(repr(obj)) == obj
str(obj) 通過給定的對象返回一個字符串(這個字符串通常是給人閱讀的)
說明:
1. str(obj) 函數(shù)先查找obj.__str__() 方法,調(diào)用此方法并返回結(jié)果
2. 如果obj.__str__() 方法不存在,則調(diào)用obj.__repr__()方法并返回結(jié)果
3. 如果obj.__repr__方法不存在,則調(diào)用object類的__repr__實例方法顯示<__main__.XXX object at 0xAABBCCDD>格式的字符串
# 此示例示意 重寫__repr__ 和 __str__方法,實現(xiàn)自定義類的# 個性化顯示class MyNumber:def __init__(self, value=
0):self.data =
valuedef __str__(self):'''此方法必須返回字符串'''print(
"__str__方法被調(diào)用")return "數(shù)字:%d" %
self.datadef __repr__(self):return "MyNumber(%d)" %
self.datan1 = MyNumber(100
)print(
"repr(n1)=", repr(n1))# print("str(n1)=", n1.__str__()) # ???print(
"str(n1) =", str(n1))
# 數(shù)字: 100print(n1)
# 內(nèi)部會調(diào)用str(n1)
n2 = MyNumber(200
)print(
"repr(n2)=", repr(n2))
# repr(n2)-->n2.__repr__() View Code 重載方法:
repr() 函數(shù)對應(yīng) def __repr__(self):
str() ---------> def __str__(self):
內(nèi)建函數(shù)的重寫
__abs__ abs(obj)
__len__ len(obj)
__reversed__ reversed(obj)
__round__ round(obj)
class MyList:def __init__(self, iterable=
()):self.data = [x
for x
in iterable]def __len__(self):'''此函數(shù)必須只有一個形參self,此函數(shù)必須返回整數(shù)'''# return self.data.__len__()return len(self.data)def __repr__(self):return 'MyList(%s)' %
self.datadef __abs__(self):L = [abs(x)
for x
in self.data]return MyList(L)
# 創(chuàng)建一個新的MyList對象并返回
myl = MyList([1, -2, 3, -4, 5
])print(len(myl))
# myl.__len__()myl2 = abs(myl)
# myl.__abs__()print(myl2)
# MyList([1, 2, 3, 4, 5]) View Code 數(shù)據(jù)轉(zhuǎn)換函數(shù)重寫
__complex__ complex(obj)
__int__ int(obj)
__float__ float(obj)
__bool__ bool(obj)
class MyNumber:def __init__(self, value=
0):self.data =
valuedef __repr__(self):return "MyNumber(%d)" %
self.datadef __int__(self):'''此方法必須返回整數(shù)'''return int(self.data)n1 = MyNumber(100
)x = int(n1)
# x = 100 # x = n1.__int__()print(x)
View Code 布爾測試函數(shù)重寫
作用:
用于bool(obj) 函數(shù)取值
用于if語句真值表達(dá)式取值
用于while 語句真值表達(dá)式取值
方法名: __bool__
說明:
當(dāng)存在__bool__方法時,調(diào)用obj.__bool__() 取值
當(dāng)不存在__bool__方法時,調(diào)用obj.__len__() 取值
當(dāng)再不存在__len__方法時,直接返回True
class MyList:def __init__(self, iterable=
()):self.data = [x
for x
in iterable]def __len__(self):'''返回0為假值,返回非零值為真值'''return len(self.data)def __bool__(self):return all(self.data)myl = MyList([1, -2, 3, -4, 5
])print(myl)print(bool(myl))
# ???if myl:print(
"真")else:print(
"假")
View Code 迭代器(高級)
迭代器可以能過next(obj) 函數(shù)取值的對象,就是迭代器
迭代器協(xié)議:
迭代器協(xié)議是指對象能夠使用next函數(shù)獲取下一項數(shù)據(jù),在沒有下一項數(shù)據(jù)時觸發(fā)一個StopIteration異常來終止迭代的約定
迭代器協(xié)議的實現(xiàn)方法:
__next__(self)
可迭代對象:
是指能用iter(obj) 函數(shù)返回迭代器的對象
可迭代對象的實現(xiàn)方法:
__iter__(self)
class MyList:def __init__(self, iterable=
()):self.data = [x
for x
in iterable]def __repr__(self):return 'MyList(%s)' %
self.datadef __iter__(self):return MyListIterator(self.data)class MyListIterator:def __init__(self, data):self.data =
dataself.cur_index = 0
# 用來記錄當(dāng)前訪問位置的索引def __next__(self):'''此方法需要實現(xiàn)迭代器協(xié)議'''if self.cur_index >=
len(self.data):raise StopIteration
# 通知調(diào)用者停止迭代r =
self.data[self.cur_index]self.cur_index += 1
return r# import timemyl = MyList([1, -2, 3, -4, 5
])print(sum(myl))
# 3print(max(myl))
# 5# it = iter(myl) # it = myl.__iter__()# while True:# try:# x = next(it) # x = it.__next__()# print(x)# time.sleep(1)# except StopIteration:# breakfor x
in myl:print(x)
# 1 -2 3 -4 5 View Code ?
轉(zhuǎn)載于:https://www.cnblogs.com/zhaoyang1997/p/10707027.html
總結(jié)
以上是生活随笔為你收集整理的python封装enclosure的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。