成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Python異常編程的小技巧集錦

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

 [[169559]]

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

如何自定義異常

定義異常類

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

 

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

 

API異常相關的技巧

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

定義API異常的技巧

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

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

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

  • socket連接超時
  • socket拒絕連接

針對以上的情況,我們在模塊中定義幾個異常:

 

  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時異常捕獲的技巧

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

 

  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.")     

 

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

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

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

捕獲Exception以提高健壯性:

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

從這兩點中可以看出,要達到這種效果,其實都要依賴于常規(guī)異常繼承于Exception類這個規(guī)矩。這樣的架構劃分所帶來的好處是顯而易見的。

與異常相關的編程藝術

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

我們經(jīng)常需要編寫一些工具類的函數(shù),往往在這些函數(shù)的處理流程中,會產(chǎn)生很多的狀態(tài);而這些狀態(tài)也是調(diào)用者需要得到的信息。很多時候,會用一些具有意義的返回值來表示函數(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)碼的方式使用起來特別的不方便,調(diào)用者還需要去理解每個狀態(tài)碼的意義,帶來其它的學習成本;而且用if-else結構也不易于后期的程序拓展。所以,我們可以使用觸發(fā)異常來代替返回狀態(tài)碼,每個異常名其實就包含了狀態(tài)的意義在內(nè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"

 

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

異常處理與流程控制

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

將異常處理與正常流程控制混為一談時,代碼是十分丑陋的。我們應該將二者分離,***的做法就是將異常代碼塊抽離到另外的函數(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() 

 

責任編輯:龐桂玉 來源: segmentfault
相關推薦

2013-02-20 15:59:50

Windows 8

2023-10-26 18:03:14

索引Python技巧

2024-01-30 00:40:10

2013-06-08 16:55:22

Nagios

2012-09-11 15:06:48

MooseFS

2024-06-04 07:46:05

2020-08-19 09:22:14

Python語言工具

2020-12-31 10:33:05

Python開發(fā)編程

2021-12-27 14:33:47

Python語言開發(fā)

2023-09-24 13:55:42

Spring應用程序

2010-09-07 10:20:21

CSS

2010-08-10 10:17:44

Flex內(nèi)存

2010-09-26 09:08:17

JVM調(diào)優(yōu)

2018-11-28 12:30:58

Python命令行編程語言

2012-12-25 09:45:08

PythonWeb

2017-01-05 14:19:06

Grep命令查找

2020-09-23 09:20:58

代碼Java字符串

2024-05-28 14:45:00

2014-12-11 13:40:15

Android Stu開發(fā)技巧

2012-11-06 12:45:46

Windows 8
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美另类视频在线 | a级黄色片在线观看 | 成年人在线观看视频 | 国产免费色 | 成人免费视频网址 | 国产美女精品 | 中文字幕第十五页 | 国产免费让你躁在线视频 | 欧美精品三区 | 亚洲一区二区在线视频 | 欧美视频在线播放 | 国产成人综合在线 | 啪啪免费网 | 欧美综合久久 | 日韩中出 | 国产高清视频 | 香蕉视频久久久 | 337p日本欧洲亚洲大胆 | 91精品国产91久久综合桃花 | 日韩免费av| 美女精品一区 | 日韩中文字幕在线观看 | 日本污视频 | 成人国产在线观看 | 一级爱爱片 | 日韩在线电影 | 国产成人免费 | aaaaaaa片毛片免费观看 | 操操操日日日 | 狠狠av | 国产一区二区三区在线免费 | 天堂在线1 | 国户精品久久久久久久久久久不卡 | 蜜桃av人人夜夜澡人人爽 | 国产美女自拍视频 | 激情毛片 | 波波电影院一区二区三区 | 九九久久精品 | 超碰综合 | 成人动漫一区二区 | 欧美黄色片|