python——面向对象篇之异常和反射
1.1 isinstance用法:
1 isinstance(string,str)
?
判斷第一個(gè)參數(shù)是否是第二個(gè)參數(shù)的子集,例如:
1.2?issubclass用法:
1 issubclass(sub, super)
? 判斷sub是否是super的派生類,返回值也是布爾值
注:使用isinstance和issubclass會(huì)破壞對(duì)象的多態(tài)性? ? ?python在遇到錯(cuò)誤后,會(huì)引發(fā)異常,如果異常對(duì)象并未被處理或者捕捉,則程序就會(huì)用所謂的回溯(traceback)來(lái)終止程序的執(zhí)行,如下所示:
1 C:\Python27\python.exe D:/python/s11/8day/反射/test.py 2 Traceback (most recent call last): 3 File "D:/python/s11/8day/test.py", line 26, in <module> 4 print isinstance(d,int) 5 NameError: name 'd' is not defined
? ? ? 在python里,每個(gè)異常都是類Exception的實(shí)例,Exception可以說(shuō)是所有異常的基類。如果我們捉住錯(cuò)誤并對(duì)其處理,那整個(gè)程序就不會(huì)回溯而是繼續(xù)執(zhí)行下去。
?2.1 被動(dòng)異常
? ? ? ? ? ? 即把代碼寫在try塊里,當(dāng)程序拋錯(cuò)時(shí)自動(dòng)觸發(fā),except則負(fù)責(zé)捕捉和處理異常,用法如下
? ? ? 在這需要注意的是:如果你print e的時(shí)候,因?yàn)檎?lái)說(shuō)print對(duì)象時(shí)返回的應(yīng)該是對(duì)象的內(nèi)存地址,而在異常處理這里,你print對(duì)象時(shí)會(huì)調(diào)用exception的__str__方法,將異常信息返回而不是返回內(nèi)存地址,所以這里你print的時(shí)候會(huì)發(fā)現(xiàn)顯示的會(huì)是異常信息,對(duì)此你不需要覺得奇怪。
? ? ? ?在except捕獲異常時(shí),你還可以在except后面再加個(gè)except,就像自來(lái)水過(guò)濾一樣一層層的捕獲特定的異常
? ? ? ?
? ? ? ? ?另一種寫法:
2.2 主動(dòng)觸發(fā)異常
? ? ? ? ? ?不等程序代碼遇到錯(cuò)誤拋出后才觸發(fā),而是我們?cè)陬A(yù)計(jì)會(huì)出現(xiàn)問(wèn)題的地方提前觸發(fā) ? ??
2.3 自定義異常
? ? ? ? ? ?既是我們自己定義異常的觸發(fā)條件和處理方法,創(chuàng)建自定義異常的時(shí)候需要直接或者間接的繼承Exception
調(diào)用自定義異常
?
2.4 finally
? ? ? ? ? ?不管try子句是否發(fā)生異常都會(huì)執(zhí)行,比如當(dāng)你在讀寫文件或者scoket通訊時(shí),不管是否出現(xiàn)異常都應(yīng)該在結(jié)束后關(guān)閉文件或者網(wǎng)絡(luò)套接字,這時(shí)就可以把關(guān)閉方法放在finally子句中
?
2.5 忽略所有異常1 try: 2 Garen = Hero 3 except: 4 pass
? ? ?這是一種比較危險(xiǎn)的用法,它會(huì)忽略程序的所有異常而繼續(xù)的讓程序執(zhí)行下去。
異常處理只需要記住一點(diǎn):當(dāng)我們知道某段代碼可能會(huì)導(dǎo)致某種異常,但我們又不希望程序停止,那么我們就可以根據(jù)需要添加異常處理。
擴(kuò)展:反射中的getattr的內(nèi)部實(shí)現(xiàn)也是通過(guò)訪問(wèn)特性并捕捉可引發(fā)的AttributeError異常區(qū)實(shí)現(xiàn)的
反射,將名稱轉(zhuǎn)換成動(dòng)詞,這是筆者看完《Execution in the Kingdom of Nouns》后對(duì)反射的第一反應(yīng),大家有興趣可以去翻閱,一篇不算太長(zhǎng)的文章。
? ? ? 下面我們來(lái)想象一下這么一個(gè)場(chǎng)景:你坐在電腦旁,玩著LOL,通過(guò)鼠標(biāo)和鍵盤傳遞信息,游戲里的英雄相應(yīng)的做出操作,這就可以看成反射。這是怎么做到的呢?讓我們往下看:
首先我們定義了一個(gè)英雄模板,也就是基類。
1 class Hero: 2 def __init__(self): 3 self.ATK = 30 4 self.DEF = 10 5 self.HP = 300 6 self.MP = 100 7 8 def walk(self): 9 print "你的英雄正走向目標(biāo)" 10 def running(self): 11 print "你的英雄正跑向目標(biāo)" 12 def skills(self): 13 print "你的英雄正在釋放技能" 14 def attack(self): 15 print "你的英雄正在攻擊"
?上面這個(gè)英雄基類里有攻擊、防御、生命和魔法值四個(gè)屬性以及走路、跑步、釋放技能和攻擊四個(gè)方法動(dòng)作。
?現(xiàn)在你在電腦前創(chuàng)建了一個(gè)角色蓋倫,程序開始把類實(shí)例化:
?
?OK,你的英雄角色已經(jīng)生成了,讓我們看看蓋倫現(xiàn)在都有什么(前面四個(gè)是屬性,后面四個(gè)是方法,中間我們先不管它):
1 print dir(Garen) 2 3 C:\Python27\python.exe D:/python/s11/8day/反射/test.py 4 5 ['ATK', 'DEF', 'HP', 'MP', '__doc__', '__init__', '__module__', 'attack', 'running', 'skills', 'walk']?
?再看看初始屬性是多少(恩,HP比MP高,看來(lái)是近戰(zhàn)英雄):
1 print Garen.__dict__ 2 3 C:\Python27\python.exe D:/python/s11/8day/反射/test.py 4 5 {'HP': 300, 'ATK': 30, 'DEF': 10, 'MP': 100}?
?既然角色生成了,那接下來(lái)當(dāng)然就該開始操作了。你用鼠標(biāo)對(duì)地圖點(diǎn)了一下,一個(gè)walk字符串傳到了后臺(tái)程序中,現(xiàn)在讓我們看看程序是怎么處理的:
1 if hasattr(Garen,"walk"): #傳入walk字符串,使用hasattr函數(shù)判斷角色是否有該方法 2 walk = getattr(Garen,"walk") #如果有則使用getattr函數(shù)取出該方法體,但不執(zhí)行 3 walk() #最后執(zhí)行該方法?
然后你的角色就會(huì)做相應(yīng)的動(dòng)作:
1 C:\Python27\python.exe D:/python/s11/8day/反射/test.py 2 3 你的英雄正走向目標(biāo)?
? ? ? 釋放技能也一樣,當(dāng)你在鍵盤按下技能快捷鍵時(shí)把對(duì)應(yīng)技能名稱發(fā)給程序,程序把名稱的技能轉(zhuǎn)換成可執(zhí)行的動(dòng)詞執(zhí)行對(duì)應(yīng)的方法。反射說(shuō)白了就是把你傳給對(duì)象的字符串參數(shù)當(dāng)成對(duì)象里的同名方法去執(zhí)行,前提是該對(duì)象有這個(gè)方法。
? ? ? 當(dāng)然,反射也不僅僅是對(duì)象專有,其他擴(kuò)展到類、模塊、函數(shù)等容器也都可以使用反射,下面就是反射的四個(gè)方法:
?
? ? ? 一般后面兩個(gè)比較少用,了解即可
? ? ?斷言是一個(gè)比較有意思的東西,它就想一個(gè)條件判斷一樣,只有滿足時(shí)才會(huì)讓程序走下去,不然就報(bào)錯(cuò)。可以用來(lái)檢測(cè)系統(tǒng)環(huán)境是否滿足程序的需要,一般在測(cè)試或者調(diào)試時(shí)使用
1 assert system == "mac" #程序只能在mac上執(zhí)行,如果不滿足則不讓執(zhí)行程序
?
? ? ?既是一個(gè)類,只實(shí)例化一次,只占用一塊內(nèi)存,各程序想用這個(gè)功能的時(shí)候就不用再實(shí)例化一個(gè)對(duì)象,而是調(diào)用同一個(gè)實(shí)例,共享內(nèi)存。
? ? ?舉例:程序會(huì)有一個(gè)專門連接數(shù)據(jù)庫(kù)的類,當(dāng)用戶查詢數(shù)據(jù)庫(kù)都會(huì)實(shí)例化一次,創(chuàng)建一個(gè)用于連接的對(duì)象,如果并發(fā)大的話會(huì)很浪費(fèi)內(nèi)存資源,使用單例實(shí)例的話就只需要實(shí)例化一次,之后大家共用一個(gè)連接實(shí)例,這樣能節(jié)省大量資源。
單例模式類的創(chuàng)建:
?
單例模式對(duì)象的創(chuàng)建:
1 obj = Foo.singleton()
?
轉(zhuǎn)載于:https://www.cnblogs.com/dengtr/p/5059030.html
總結(jié)
以上是生活随笔為你收集整理的python——面向对象篇之异常和反射的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 跨域请求获取Solr json检索结果并
- 下一篇: python 文件流