day23-多态和
# 多態(tài)
什么是多態(tài)?
# 一種事物具備多種不同的形態(tài) 例如:水 固態(tài) 氣態(tài) 液態(tài) ?大黃蜂:汽車人,汽車,飛機 # 官方解釋: 多個不同類對象可以響應(yīng)同一個方法,產(chǎn)生不同的結(jié)果 首先強調(diào)多態(tài)不是一種特殊的語法,而是一種狀態(tài),特性(既多個不同對象可以響應(yīng)同一個方法,產(chǎn)生不同的結(jié)果),既多個對象有相同的使用方法?
?
為什么要用多態(tài)?
# 對于使用者而言,大大的降低了使用難度,我們之前寫的USB接口下的鼠標(biāo),鍵盤,就屬于多態(tài)?
怎么實現(xiàn)多態(tài)?
# 接口 抽象類 鴨子類型 都可以寫出具備多態(tài)的代碼,最簡單的就是鴨子類型?
案例:
# 多態(tài),不同的對象響應(yīng)同一個方法,產(chǎn)生不同的結(jié)果,吃,走,下蛋class Ji:def dawn(self):print("咯咯咯")def egg(self):print("下雞蛋")class Duck:def dawn(self):print('嘎嘎嘎')def egg(self):print('下鴨蛋')class E:def dawn(self):print("餓餓餓")def egg(self):print('下鵝蛋')j = Ji() y = Duck() e = E()def manage(obj):obj.dawn()def get_egg(obj):obj.egg()manage(j) manage(y) manage(e) get_egg(j) get_egg(y) get_egg(e)?
?
OOP中的內(nèi)置函數(shù)
isinstance
# 判斷一個對象是否是某個類的實例 參數(shù)1 要判斷的對象參數(shù)2 要判斷的類型?
運用
def add_num(a, b):if isinstance(a, int) and isinstance(b, int):return a + breturn Noneprint(add_num(23, 97)) print(add_num(12.7, 76))?
?
## issubclass
# 判斷一個類是否是另一個類的子類 參數(shù)一是子類參數(shù)二是父類?
運用
class Animal:def eat(self):print("動物得吃東西...")class Pig(Animal):def eat(self):print("豬得吃 豬食....")class Tree:def light(self):print("植物光合作用....")pig = Pig() t = Tree()def manage(obj):if issubclass(type(obj), obj):obj.eat()else:print("不是一頭動物!")manage(pig)manage(t)?
類中的魔法函數(shù)
str
__str__ 會在對象被轉(zhuǎn)換為字符串時,轉(zhuǎn)換的結(jié)果就是這個函數(shù)的返回值 使用場景:我們可以利用該函數(shù)來自定義,對象的是打印格式?
運用
import timeclass Person:def __init__(self, name, age):self.name = nameself.age = agedef __str__(self):return "這是一個person對象,name:%s,age:%s" % (self.name, self.age)def __del__(self):print("del run")p = Person('jack', 20)time.sleep(2)print('over')del
# 執(zhí)行時機: 手動刪除對象時立馬執(zhí)行,或是程序運行結(jié)束時也會自動執(zhí)行 # 使用場景:當(dāng)你的對象在使用過程中,打開了不屬于解釋器的資源:例如文件,網(wǎng)絡(luò)端口使用案例
class FileTool: """該類用于簡化文件的讀寫操作 """def __init__(self,path): self.file = open(path,"rt",encoding="utf-8") self.a = 100def read(self): return self.file.read()# 在這里可以確定一個事,這個對象肯定不使用了 所以可以放心的關(guān)閉問文件了 def __del__(self): self.file.close()tool = FileTool("a.txt") print(tool.read())call
# 執(zhí)行時機:在調(diào)用對象時自動執(zhí)行,(既對象加括號)?
使用
#call 的執(zhí)行時機 class A:def __call__(self, *args, **kwargs):print("call run")print(args)print(kwargs)a = A() a(1,a=100)?
slots
# 該屬性是一個類屬性,用于優(yōu)化對象內(nèi)存占用,優(yōu)化的原理,將原本不固定的屬性數(shù)量,變得固定了,這樣的解釋器就不會為這個對象創(chuàng)建名稱空間,所以__dict__也沒了,從而達到減少內(nèi)存開銷的效果 # 另外當(dāng)類中出現(xiàn)了slots時將導(dǎo)致這個類的對象無法在添加新的屬性slots的使用
class Person:__slots__ = ["name"] def __init__(self,name): self.name = namep = Person("jck")# 查看內(nèi)存占用 # print(sys.getsizeof(p)) # p.age = 20 # 無法添加# dict 沒有了 print(p.__dict__)?
getattr setattr delattr
# getattr 用點訪問屬性的時如果屬性不存在時執(zhí)行 # setattr 用點設(shè)置屬性時 # delattr 用del 對象.屬性 刪除屬性時 執(zhí)行 這幾個函數(shù)反映了 python解釋器是如何實現(xiàn) 用點來訪問屬性getattribute 該函數(shù)也是用來獲取屬性 在獲取屬性時如果存在getattribute則先執(zhí)行該函數(shù),如果沒有拿到屬性則繼續(xù)調(diào)用 getattr函數(shù),如果拿到了則直接返回[] 的實原理
# getitem setitem delitem 任何的符號 都會被解釋器解釋成特殊含義 ,例如 . [] ()getitem 當(dāng)你用中括號去獲取屬性時 執(zhí)行 setitem 當(dāng)你用中括號去設(shè)置屬性時 執(zhí)行 delitem 當(dāng)你用中括號去刪除屬性時 執(zhí)行運算符重載
# 當(dāng)我們在使用某個符號時,python解釋器都會為這個符號定義一個含義,同時調(diào)用對應(yīng)的處理函數(shù),# 當(dāng)我們需要自定義對象的比較規(guī)則時,就可在子類中覆蓋 大于 等于 等一系列方法....
?
案例:
原本自定義對象無法直接使用大于小于來進行比較 ,我們可自定義運算符來實現(xiàn),讓自定義對象也支持比較運算符
class Student(object):def __init__(self,name,height,age):self.name = nameself.height = heightself.age = agedef __gt__(self, other):# print(self)# print(other)# print("__gt__")return self.height > other.heightdef __lt__(self, other):return self.height < other.heightdef __eq__(self, other):if self.name == other.name and self.age == other.age and self.height == other.height:return Truereturn Falsestu1 = Student("jack",180,28) stu2 = Student("jack",180,28) # print(stu1 < stu2) print(stu1 == stu2)?
?
上述代碼中,other指的是另一個參與比較的對象,
大于和小于只要實現(xiàn)一個即可,符號如果不同 解釋器會自動交換兩個對象的位置
?
迭代器協(xié)議
# 迭代器是指具有__iter__和__next__的對象 我們可以為對象增加這兩個方法來讓對象變成一個迭代器?
案例
class MyRange:def __init__(self,start,end,step):self.start = startself.end = endself.step = stepdef __iter__(self):return selfdef __next__(self):a = self.startself.start += self.stepif a < self.end:return aelse:raise StopIterationfor i in MyRange(1,10,2):print(i)?
上下文管理
# 上下文 context 這個概念屬于語言學(xué)科,指的是一段話的意義,要參考當(dāng)前的場景,既上下文 在python中,上下文可以理解為是一個代碼區(qū)間,一個范圍 ,例如with open 打開的文件僅在這個上下文中有效 涉及到的兩個方法:# enter 表示進入上下文,(進入某個場景 了) # exit 表示退出上下文,(退出某個場景 了)當(dāng)執(zhí)行with 語句時,會先執(zhí)行enter , 當(dāng)代碼執(zhí)行完畢后執(zhí)行exit,或者代碼遇到了異常會立即執(zhí)行exit,并傳入錯誤信息 包含錯誤的類型.錯誤的信息.錯誤的追蹤信息?
?
注意
enter 函數(shù)應(yīng)該返回對象自己 exit函數(shù) 可以有返回值,是一個bool類型,用于表示異常是否被處理,僅在上下文中出現(xiàn)異常有用 如果為True 則意味著,異常以及被處理了 False,異常未被處理,程序?qū)⒅袛鄨箦e?
?
# 對于使用者而言,大大的降低了使用難度,我們之前寫的USB接口下的鼠標(biāo),鍵盤,就屬于多態(tài)?
轉(zhuǎn)載于:https://www.cnblogs.com/Ryan-Yuan/p/11265143.html
總結(jié)
- 上一篇: java并发编程-----深入剖析Thr
- 下一篇: SpringBoot无法找到加载类 ,应