国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

總結(jié):Python中的異常處理

douzifly / 2076人閱讀

摘要:盡量使用內(nèi)置的異常處理語(yǔ)句來(lái)替換語(yǔ)句,比如語(yǔ)句,方法。以上是最簡(jiǎn)單的重新拋出異常的做法,也是推薦的做法。除了包含所有的外還包含了,和三個(gè)異常。避免在語(yǔ)句塊中干一些沒意義的事情,捕獲異常也是需要成本的。

異常處理在任何一門編程語(yǔ)言里都是值得關(guān)注的一個(gè)話題,良好的異常處理可以讓你的程序更加健壯,清晰的錯(cuò)誤信息更能幫助你快速修復(fù)問題。在Python中,和不部分高級(jí)語(yǔ)言一樣,使用了try/except/finally語(yǔ)句塊來(lái)處理異常,如果你有其他編程語(yǔ)言的經(jīng)驗(yàn),實(shí)踐起來(lái)并不難。

異常處理語(yǔ)句 try...excpet...finally 實(shí)例代碼
def div(a, b):
    try:
        print(a / b)
    except ZeroDivisionError:
        print("Error: b should not be 0 !!")
    except Exception as e:
        print("Unexpected Error: {}".format(e))
    else:
        print("Run into else only when everything goes well")
    finally:
        print("Always run into finally block.")

# tests
div(2, 0)
div(2, "bad type")
div(1, 2)

# Mutiple exception in one line
try:
    print(a / b)
except (ZeroDivisionError, TypeError) as e:
    print(e)

# Except block is optional when there is finally
try:
    open(database)
finally:
    close(database)

# catch all errors and log it
try:
    do_work()
except:    
    # get detail from logging module
    logging.exception("Exception caught!")
    
    # get detail from sys.exc_info() method
    error_type, error_value, trace_back = sys.exc_info()
    print(error_value)
    raise
總結(jié)如下

except語(yǔ)句不是必須的,finally語(yǔ)句也不是必須的,但是二者必須要有一個(gè),否則就沒有try的意義了。

except語(yǔ)句可以有多個(gè),Python會(huì)按except語(yǔ)句的順序依次匹配你指定的異常,如果異常已經(jīng)處理就不會(huì)再進(jìn)入后面的except語(yǔ)句。

except語(yǔ)句可以以元組形式同時(shí)指定多個(gè)異常,參見實(shí)例代碼。

except語(yǔ)句后面如果不指定異常類型,則默認(rèn)捕獲所有異常,你可以通過logging或者sys模塊獲取當(dāng)前異常。

如果要捕獲異常后要重復(fù)拋出,請(qǐng)使用raise,后面不要帶任何參數(shù)或信息。

不建議捕獲并拋出同一個(gè)異常,請(qǐng)考慮重構(gòu)你的代碼。

不建議在不清楚邏輯的情況下捕獲所有異常,有可能你隱藏了很嚴(yán)重的問題。

盡量使用內(nèi)置的異常處理語(yǔ)句來(lái)替換try/except語(yǔ)句,比如with語(yǔ)句,getattr()方法。

拋出異常 raise

如果你需要自主拋出異常一個(gè)異常,可以使用raise關(guān)鍵字,等同于C#和Java中的throw,其語(yǔ)法規(guī)則如下。

raise NameError("bad name!")

raise關(guān)鍵字后面可以指定你要拋出的異常實(shí)例,一般來(lái)說(shuō)拋出的異常越詳細(xì)越好,Python在exceptions模塊內(nèi)建了很多的異常類型,通過使用dir()函數(shù)來(lái)查看exceptions中的異常類型,如下:

import exceptions

print dir(exceptions)
# ["ArithmeticError", "AssertionError"...]

當(dāng)然你也可以查閱Python的文檔庫(kù)進(jìn)行更詳細(xì)的了解。

https://docs.python.org/2.7/l...

自定義異常類型

Python中自定義自己的異常類型非常簡(jiǎn)單,只需要要從Exception類繼承即可(直接或間接):

class SomeCustomException(Exception):
    pass

class AnotherException(SomeCustomException):
    pass

一般你在自定義異常類型時(shí),需要考慮的問題應(yīng)該是這個(gè)異常所應(yīng)用的場(chǎng)景。如果內(nèi)置異常已經(jīng)包括了你需要的異常,建議考慮使用內(nèi)置的異常類型。比如你希望在函數(shù)參數(shù)錯(cuò)誤時(shí)拋出一個(gè)異常,你可能并不需要定義一個(gè)InvalidArgumentError,使用內(nèi)置的ValueError即可。

經(jīng)驗(yàn)案例 傳遞異常 re-raise Exception

捕捉到了異常,但是又想重新拋出它(傳遞異常),使用不帶參數(shù)的raise語(yǔ)句即可:

def f1():
    print(1/0)

def f2():
    try:
        f1()
    except Exception as e:
        raise  # don"t raise e !!!

f2()

在Python2中,為了保持異常的完整信息,那么你捕獲后再次拋出時(shí)千萬(wàn)不能在raise后面加上異常對(duì)象,否則你的trace信息就會(huì)從此處截?cái)?/strong>。以上是最簡(jiǎn)單的重新拋出異常的做法,也是推薦的做法。

還有一些技巧可以考慮,比如拋出異常前你希望對(duì)異常的信息進(jìn)行更新。

def f2():
    try:
        f1()
    except Exception as e:
        e.args += ("more info",)
        raise

如果你有興趣了解更多,建議閱讀這篇博客。

http://www.ianbicking.org/blo...

Python3對(duì)重復(fù)傳遞異常有所改進(jìn),你可以自己嘗試一下,不過建議還是遵循以上規(guī)則。

Exception 和 BaseException

當(dāng)我們要捕獲一個(gè)通用異常時(shí),應(yīng)該用Exception還是BaseException?我建議你還是看一下 官方文檔說(shuō)明,這兩個(gè)異常到底有啥區(qū)別呢? 請(qǐng)看它們之間的繼承關(guān)系。

BaseException
 +-- SystemExit
 +-- KeyboardInterrupt
 +-- GeneratorExit
 +-- Exception
      +-- StopIteration...
      +-- StandardError...
      +-- Warning...

Exception的層級(jí)結(jié)構(gòu)來(lái)看,BaseException是最基礎(chǔ)的異常類,Exception繼承了它。BaseException除了包含所有的Exception外還包含了SystemExitKeyboardInterruptGeneratorExit三個(gè)異常。

由此看來(lái)你的程序在捕獲所有異常時(shí)更應(yīng)該使用Exception而不是BaseException,因?yàn)楸慌懦娜齻€(gè)異常屬于更高級(jí)別的異常,合理的做法應(yīng)該是交給Python的解釋器處理。

except Exception as e和 except Exception, e

代碼示例如下:

try:
    do_something()
except NameError as e:  # should
    pass
except KeyError, e:  # should not
    pass

在Python2的時(shí)代,你可以使用以上兩種寫法中的任意一種。在Python3中你只能使用第一種寫法,第二種寫法已經(jīng)不再支持。第一個(gè)種寫法可讀性更好,而且為了程序的兼容性和后期移植的成本,請(qǐng)你果斷拋棄第二種寫法。

raise "Exception string"

把字符串當(dāng)成異常拋出看上去是一個(gè)非常簡(jiǎn)潔的辦法,但其實(shí)是一個(gè)非常不好的習(xí)慣。

if is_work_done():
    pass
else:
    raise "Work is not done!" # not cool

上面的語(yǔ)句如果拋出異常,那么會(huì)是這樣的:

Traceback (most recent call last):
  File "/demo/exception_hanlding.py", line 48, in 
    raise "Work is not done!"
TypeError: exceptions must be old-style classes or derived from BaseException, not str

這在 Python2.4 以前是可以接受的做法,但是沒有指定異常類型有可能會(huì)讓下游沒辦法正確捕獲并處理這個(gè)異常,從而導(dǎo)致你的程序難以維護(hù)。簡(jiǎn)單說(shuō),這種寫法是是封建時(shí)代的陋習(xí),應(yīng)該扔了。

使用內(nèi)置的語(yǔ)法范式代替try/except

Python 本身提供了很多的語(yǔ)法范式簡(jiǎn)化了異常的處理,比如for語(yǔ)句就處理了的StopIteration異常,讓你很流暢地寫出一個(gè)循環(huán)。

with語(yǔ)句在打開文件后會(huì)自動(dòng)調(diào)用finally并關(guān)閉文件。我們?cè)趯?Python 代碼時(shí)應(yīng)該盡量避免在遇到這種情況時(shí)還使用try/except/finally的思維來(lái)處理。

# should not
try:
    f = open(a_file)
    do_something(f)
finally:
    f.close()

# should 
with open(a_file) as f:
    do_something(f)

再比如,當(dāng)我們需要訪問一個(gè)不確定的屬性時(shí),有可能你會(huì)寫出這樣的代碼:

try:
    test = Test()
    name = test.name  # not sure if we can get its name
except AttributeError:
    name = "default"

其實(shí)你可以使用更簡(jiǎn)單的getattr()來(lái)達(dá)到你的目的。

name = getattr(test, "name", "default")
最佳實(shí)踐

最佳實(shí)踐不限于編程語(yǔ)言,只是一些規(guī)則和填坑后的收獲。

只處理你知道的異常,避免捕獲所有異常然后吞掉它們。

拋出的異常應(yīng)該說(shuō)明原因,有時(shí)候你知道異常類型也猜不出所以然。

避免在catch語(yǔ)句塊中干一些沒意義的事情,捕獲異常也是需要成本的。

不要使用異常來(lái)控制流程,那樣你的程序會(huì)無(wú)比難懂和難維護(hù)。

如果有需要,切記使用finally來(lái)釋放資源。

如果有需要,請(qǐng)不要忘記在處理異常后做清理工作或者回滾操作。

關(guān)于作者:Python技術(shù)愛好者,目前從事測(cè)試開發(fā)相關(guān)工作,轉(zhuǎn)載請(qǐng)注明原文出處。

歡迎關(guān)注我的博客 https://betacat.online,你可以到我的公眾號(hào)中去當(dāng)吃瓜群眾。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/38259.html

相關(guān)文章

  • python---異常處理

    摘要:總結(jié)判斷式的異常處理只能針對(duì)某一段代碼,對(duì)于不同的代碼段的相同類型的錯(cuò)誤你需要寫重復(fù)的來(lái)進(jìn)行處理。提示是基于文件句柄而存在的,因而只能在拋出異常后才可以執(zhí)行異常類只能用來(lái)處理指定的異常情況,如果非指定異常則無(wú)法處理。 異常和錯(cuò)誤 程序中難免出現(xiàn)錯(cuò)誤,而錯(cuò)誤分成兩種 1.語(yǔ)法錯(cuò)誤(這種錯(cuò)誤,根本過不了python解釋器的語(yǔ)法檢測(cè),必須在程序執(zhí)行前就改正) #語(yǔ)法錯(cuò)誤示范一 if #語(yǔ)法...

    Alfred 評(píng)論0 收藏0
  • Python常見異常問題總結(jié)

      小編寫這篇文章的一個(gè)主要目的,就是來(lái)給大家去做一個(gè)解答,解答的內(nèi)容主要是Python常見的一些bug和異常問題,那么,遇到這些問題的時(shí)候,我們需要找到好辦法去進(jìn)行處理。那么,小編這邊就給大家做了一個(gè)總結(jié),總結(jié)常見的異常問題,大家好好閱讀哦。  異常處理介紹  在實(shí)際的開發(fā)中,我們經(jīng)常遇到一些報(bào)錯(cuò)的例子,在pycharm的顯示頁(yè)面下,當(dāng)我們看到一串串的紅色的英文字母的時(shí)候,就是出現(xiàn)異常,這個(gè)時(shí)候...

    89542767 評(píng)論0 收藏0
  • 從JavaScript到Python異常

    摘要:但如果忽視異常輕則影響功能運(yùn)行,重則導(dǎo)致系統(tǒng)崩潰,造成經(jīng)濟(jì)損失。異常處理捕獲異常捕獲關(guān)鍵字與一致,都是使用。語(yǔ)句塊表示無(wú)論是否發(fā)生異常,語(yǔ)句塊代碼一定會(huì)被執(zhí)行。 不少前端工程師看到這個(gè)標(biāo)題可能會(huì)產(chǎn)生質(zhì)問: 我js用得好好的,能后端能APP,為什么還要學(xué)習(xí)Python? 至少有下面兩個(gè)理由: 學(xué)習(xí)曲線。ES6之后的JavaScript(TypeScript)的在語(yǔ)法上和Python有很...

    xcold 評(píng)論0 收藏0
  • Python-爬蟲工程師-面試總結(jié)

    摘要:內(nèi)存池機(jī)制提供了對(duì)內(nèi)存的垃圾收集機(jī)制,但是它將不用的內(nèi)存放到內(nèi)存池而不是返回給操作系統(tǒng)。為了加速的執(zhí)行效率,引入了一個(gè)內(nèi)存池機(jī)制,用于管理對(duì)小塊內(nèi)存的申請(qǐng)和釋放。 注:答案一般在網(wǎng)上都能夠找到。1.對(duì)if __name__ == main的理解陳述2.python是如何進(jìn)行內(nèi)存管理的?3.請(qǐng)寫出一段Python代碼實(shí)現(xiàn)刪除一個(gè)list里面的重復(fù)元素4.Python里面如何拷貝一個(gè)對(duì)象?...

    antz 評(píng)論0 收藏0
  • Python的中文編碼問題

    摘要:使用中文替代中文中文編碼中文編碼中有以上兩種聲明字符串變量的方式,它們的主要區(qū)別是編碼格式的不同,其中,的編碼格式和文件聲明的編碼格式一致,而的編碼格式則是。 字符串是Python中最常用的數(shù)據(jù)類型,而且很多時(shí)候你會(huì)用到一些不屬于標(biāo)準(zhǔn)ASCII字符集的字符,這時(shí)候代碼就很可能拋出UnicodeDecodeError: ascii codec cant decode byte 0xc4 ...

    Cheriselalala 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<