日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > python >内容正文

python

python——面向对象篇之异常和反射

發(fā)布時(shí)間:2024/6/21 python 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python——面向对象篇之异常和反射 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
  • 內(nèi)置函數(shù)isinstance和issubclass

    1.1 isinstance用法:
    1 isinstance(string,str)

    ?
    判斷第一個(gè)參數(shù)是否是第二個(gè)參數(shù)的子集,例如:

    1 print isinstance("test",str) #判斷test是否是字符串類型 2 3 C:\Python27\python.exe D:/python/s11/8day/反射/test.py 4 5 True 6 7 8 print isinstance(123,int) #判斷123是否是整型類型 9 10 C:\Python27\python.exe D:/python/s11/8day/反射/test.py 11 12 True ? 還可以判斷對(duì)象是否某一個(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é)捕捉和處理異常,用法如下

    1 try: 2 代碼塊 3 except Exception,e: #e是exception的實(shí)例,是一個(gè)對(duì)象;上面的錯(cuò)誤信息都封裝在e中 4 異常處理 #在這里你可以打印異常信息,如(print e);也可以做其他操作如把異常信息寫入日志

    ? ? ? 在這需要注意的是:如果你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ò)濾一樣一層層的捕獲特定的異常

    1 try: 2 代碼塊 3 except KeyError,e: #試圖訪問(wèn)字典里不存在的鍵 4 print e 5 except ValueError,e: #傳入一個(gè)調(diào)用者不期望的值,即使值的類型是正確的 6 print e 7 except Exception,e: #如果你無(wú)法預(yù)期會(huì)發(fā)生什么異常,那好,我們還有個(gè)萬(wàn)能異常 8 print e

    ? ? ? ?
    ? ? ? ? ?另一種寫法:

    1 try: 2 Garen = Hero 3 except (KeyError,ValueError),e: #寫成元組形式 4 print e



    2.2 主動(dòng)觸發(fā)異常
    ? ? ? ? ? ?不等程序代碼遇到錯(cuò)誤拋出后才觸發(fā),而是我們?cè)陬A(yù)計(jì)會(huì)出現(xiàn)問(wèn)題的地方提前觸發(fā) ? ??

    1 try: 2 raise Exception('這里出現(xiàn)錯(cuò)誤') #提前傳參并實(shí)例化異常 3 except Exception,e: #把錯(cuò)誤信息封裝到exception的實(shí)例e里 4 print e


    2.3 自定義異常
    ? ? ? ? ? ?既是我們自己定義異常的觸發(fā)條件和處理方法,創(chuàng)建自定義異常的時(shí)候需要直接或者間接的繼承Exception

    1 class testError(exception): //繼承exception異常基類 2 def __init__(self,msg=None): 3 self.msg = msg 4 def __str__(self): 5 if self.msg: //根據(jù)傳入的參數(shù)動(dòng)態(tài)顯示異常信息 6 return self.msg 7 else: 8 return "自定義異常" //默認(rèn)異常顯示信息


    調(diào)用自定義異常

    1 try: 2 raise testError() //實(shí)例化自定義異常類,后面括號(hào)可傳入?yún)?shù) 3 except testError,e: 4 print e

    ?

    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子句中

    1 try: 2 f = open("test.txt","a") 3 f.write(data) 4 except Exception,e: 5 print e 6 finally: 7 f.close()

    ?

    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í)例化:

    1 Garen = Hero()

    ?

    ?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è)方法:

    1 hasattr():根據(jù)輸入?yún)?shù)判斷某個(gè)容器中是否有已該參數(shù)為名稱的內(nèi)容,如果有則返回true 2 getattr():取出容器中以參數(shù)為名稱的內(nèi)容 3 setattr():對(duì)容器中以參數(shù)為名稱的內(nèi)容進(jìn)行修改 4 delattr():刪除容器中以參數(shù)為名稱的內(nèi)容

    ?

    ? ? ? 一般后面兩個(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)建:

    1 1 class Foo(object): 2 2 __instance = None #_instance設(shè)為None,表明該類還沒有實(shí)例化過(guò) 3 3 4 4 @staticmethod #設(shè)為靜態(tài)方法 5 5 def singleton(): 6 6 if Foo.__instance: #判斷是否實(shí)例化過(guò),如果__instance存在則不再創(chuàng)建實(shí)例,而是直接返回第一次創(chuàng)建的實(shí)例 7 7 return Foo.__instance 8 8 else: 9 9 Foo.__instance = Foo() #如果還沒有實(shí)例化過(guò),則將實(shí)例化的對(duì)象實(shí)例綁定到__instance上,并返回該實(shí)例 10 10 return Foo.__instance

    ?

    單例模式對(duì)象的創(chuàng)建:

    1 obj = Foo.singleton()
  •   

    ?

    轉(zhuǎn)載于:https://www.cnblogs.com/dengtr/p/5059030.html

    總結(jié)

    以上是生活随笔為你收集整理的python——面向对象篇之异常和反射的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。