日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
Python異常編程的小技巧集錦

編程中經(jīng)常會(huì)需要使用到異常處理的情況,在閱讀了一些資料后,整理了關(guān)于異常處理的一些小技巧記錄如下。

創(chuàng)新互聯(lián)致力于成都網(wǎng)站建設(shè)、成都網(wǎng)站制作,成都網(wǎng)站設(shè)計(jì),集團(tuán)網(wǎng)站建設(shè)等服務(wù)標(biāo)準(zhǔn)化,推過(guò)標(biāo)準(zhǔn)化降低中小企業(yè)的建站的成本,并持續(xù)提升建站的定制化服務(wù)水平進(jìn)行質(zhì)量交付,讓企業(yè)網(wǎng)站從市場(chǎng)競(jìng)爭(zhēng)中脫穎而出。 選擇創(chuàng)新互聯(lián),就選擇了安全、穩(wěn)定、美觀的網(wǎng)站建設(shè)服務(wù)!

如何自定義異常

定義異常類

在實(shí)際編程中,有時(shí)會(huì)發(fā)現(xiàn)Python提供的內(nèi)建異常的不夠用,我們需要在特殊業(yè)務(wù)場(chǎng)景下的異常。這時(shí)就需要我們來(lái)定義自己的異常。按照Python約定俗成的習(xí)慣,用戶定義的異常一般都是繼承于Exception類,由它開(kāi)始拓展。后面我們可以看到這樣做在捕獲異常的時(shí)候會(huì)帶來(lái)很大的便利。

 
 
  1. >>> class MyError(Exception): 
  2.         pass 
  3.  
  4. >>> raise MyError(u"something error") 
  5. Traceback (most recent call last): 
  6.   File "", line 1, in  
  7. __main__.MyError: something error   

API異常相關(guān)的技巧

API的異常分為定義異常與調(diào)用API時(shí)如何捕獲異常兩個(gè)部分,這二者相輔相成。

定義API異常的技巧

在自己編寫API的時(shí)候,應(yīng)該定義Root Exception——API中的根異常,其它異常都繼承于它。這樣的做法有兩個(gè)好處:

  • API代碼層次更清晰
  • API與調(diào)用程序代碼隔離

假設(shè)存在如下場(chǎng)景:需要做一個(gè)鏈接數(shù)據(jù)庫(kù)服務(wù)的模塊。提供一個(gè)connect函數(shù)用于鏈接。那么,在鏈接的過(guò)程中,就會(huì)發(fā)生以下幾種情況:

  • socket連接超時(shí)
  • socket拒絕連接

針對(duì)以上的情況,我們?cè)谀K中定義幾個(gè)異常:

 
 
  1. # database.py 
  2. class Error(Exception): 
  3.     """Root exception for all exceptions raised by this module.""" 
  4.      
  5. class SocketTimeError(Error): 
  6.     pass 
  7.  
  8. class SocketRefuseError(Error): 
  9.     pass 
  10.      
  11. def connect(): 
  12.     pass   

調(diào)用API時(shí)異常捕獲的技巧

這樣在調(diào)用API的時(shí)候就可以這樣使用:

 
 
  1. try: 
  2.     connect() 
  3. except SocketTimeError as err: 
  4.     log.error(err) 
  5. except SocketRefuseError as err: 
  6.     log.error(err) 
  7. except Error as err: 
  8.     log.error("API Unexpected error:%s" % err) 
  9. except Exception: 
  10.     log.error("API bug cause exception.")     

這樣精確定義多個(gè)異常,使得代碼層次清晰,增強(qiáng)了可讀性。值得注意的是:在代碼的***還捕獲了Error以及Exception兩個(gè)異常,這兩個(gè)操作分別對(duì)應(yīng)于可拓展性與健壯性的目的。

捕獲Root Exception以提高可拓展性:

我們知道,在實(shí)際鏈接數(shù)據(jù)庫(kù)時(shí),還可能會(huì)出現(xiàn)用戶沒(méi)有登陸權(quán)限等問(wèn)題。所以,我們需要在下一個(gè)版本中加入PermissionDeny這個(gè)異常。但是,舊的調(diào)用代碼已經(jīng)寫好了,如果忘記修改的話,這個(gè)異??赡芫蜁?huì)無(wú)法被處理,進(jìn)而使得調(diào)用的程序奔潰。處于這樣的考慮,我們?cè)谡{(diào)用API的時(shí)候,就應(yīng)該再捕獲API的Root Exception,即使之后新加入了其它的異常,在這一個(gè)except中也能被捕獲而不影響調(diào)用程序。使得API模塊的可拓展性得到了提高。

捕獲Exception以提高健壯性:

在調(diào)用API的時(shí)候,難免可能出現(xiàn)API內(nèi)部存在bug的情況。這個(gè)時(shí)候如果捕獲了Exception的話,就算API內(nèi)部因?yàn)閎ug發(fā)生了異常,也不會(huì)影響到調(diào)用程序的正常運(yùn)行。

從這兩點(diǎn)中可以看出,要達(dá)到這種效果,其實(shí)都要依賴于常規(guī)異常繼承于Exception類這個(gè)規(guī)矩。這樣的架構(gòu)劃分所帶來(lái)的好處是顯而易見(jiàn)的。

與異常相關(guān)的編程藝術(shù)

異常代替返回狀態(tài)碼

我們經(jīng)常需要編寫一些工具類的函數(shù),往往在這些函數(shù)的處理流程中,會(huì)產(chǎn)生很多的狀態(tài);而這些狀態(tài)也是調(diào)用者需要得到的信息。很多時(shí)候,會(huì)用一些具有意義的返回值來(lái)表示函數(shù)處理的狀態(tài)。

比如:

 
 
  1. def write(content): 
  2.     if isinstance(content, basestring): 
  3.         f_handler = open("file.txt", 'w') 
  4.         try: 
  5.             f_handler.write(context) 
  6.             except Exception: 
  7.                 return -2    # write file fail 
  8.         else: 
  9.             return 0    # write file succcess 
  10.         finally: 
  11.             f_hanlder.close() 
  12.     else: 
  13.         return -1    # arg type error 

調(diào)用代碼:

 
 
  1. result = write() 
  2. if result == -1: 
  3.     log.error(u"type error") 
  4. elif result = -2: 
  5.     log.error(u"write error") 
  6. else: 
  7.     log.info("ok")     

這種狀態(tài)碼的方式使用起來(lái)特別的不方便,調(diào)用者還需要去理解每個(gè)狀態(tài)碼的意義,帶來(lái)其它的學(xué)習(xí)成本;而且用if-else結(jié)構(gòu)也不易于后期的程序拓展。所以,我們可以使用觸發(fā)異常來(lái)代替返回狀態(tài)碼,每個(gè)異常名其實(shí)就包含了狀態(tài)的意義在內(nèi)(命名的藝術(shù)),使用起來(lái)也更好理解。

使用異常的方式:

 
 
  1. class Error(Exception): 
  2.     pass 
  3.      
  4. class OpenFileError(Error): 
  5.     pass 
  6.      
  7. class WriteContentError(Error): 
  8.     pass     
  9.  
  10. def write(content): 
  11.     if isinstance(content, basestring): 
  12.         f_handler = open("file.txt", 'w') 
  13.         try: 
  14.             f_handler.write(context) 
  15.             except Exception: 
  16.                 raise WriteContentError 
  17.         finally: 
  18.             f_hanlder.close() 
  19.     else: 
  20.         raise OpenFileError 

調(diào)用代碼:

 
 
  1. try: 
  2.     write() 
  3. except OpenFileError as e: 
  4.     log.error(e) 
  5. except WriteContentError as e: 
  6.     log.error(e) 
  7. except Error: 
  8.     log.error("API Error") 
  9. except Exception 
  10.     log.error("API Bug")     
  11. else: 
  12.     log.info("ok") 

結(jié)合上面一點(diǎn)提到的使用API時(shí)的異常捕獲,使得調(diào)用代碼變得更佳靈活。

異常處理與流程控制

錯(cuò)誤處理很重要,但如果它搞亂了代碼邏輯,就是錯(cuò)誤的做法

將異常處理與正常流程控制混為一談時(shí),代碼是十分丑陋的。我們應(yīng)該將二者分離,***的做法就是將異常代碼塊抽離到另外的函數(shù)中。

 
 
  1. try: 
  2.     action_a() 
  3.     action_b() 
  4.     action_c() 
  5. except ActionException as e: 
  6.     log.error(e) 
  7. else: 
  8.     action_d()    

將異常處理分離:

 
 
  1. def action_executor(): 
  2.     action_a() 
  3.     action_b() 
  4.     action_c() 
  5.      
  6. def action(): 
  7.     try: 
  8.         action_executor() 
  9.     except ActionException as e: 
  10.         log.error(e) 
  11.          
  12. action() 
  13. action_d() 

文章題目:Python異常編程的小技巧集錦
文章URL:http://www.5511xx.com/article/cdghjih.html