在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ Python/ 錯(cuò)誤和異常 (1)
標(biāo)準(zhǔn)庫(kù) (4)
如何成為 Python 高手
標(biāo)準(zhǔn)庫(kù) (6)
標(biāo)準(zhǔn)庫(kù) (3)
類(2)
Pandas 使用 (2)
xml
用 tornado 做網(wǎng)站 (5)
文件(1)
練習(xí)
列表(3)
從小工到專家
除法
錯(cuò)誤和異常 (2)
函數(shù)(1)
用 tornado 做網(wǎng)站 (7)
為做網(wǎng)站而準(zhǔn)備
函數(shù)練習(xí)
標(biāo)準(zhǔn)庫(kù) (8)
Pandas 使用 (1)
回顧 list 和 str
字典(1)
用 tornado 做網(wǎng)站 (3)
字符串(1)
函數(shù)(2)
寫(xiě)一個(gè)簡(jiǎn)單的程序
將數(shù)據(jù)存入文件
語(yǔ)句(5)
SQLite 數(shù)據(jù)庫(kù)
集成開(kāi)發(fā)環(huán)境(IDE)
集合(1)
類(1)
用 tornado 做網(wǎng)站 (6)
用 tornado 做網(wǎng)站 (2)
自省
語(yǔ)句(4)
錯(cuò)誤和異常 (1)
用 tornado 做網(wǎng)站 (4)
集合(2)
列表(1)
標(biāo)準(zhǔn)庫(kù) (1)
生成器
mysql 數(shù)據(jù)庫(kù) (1)
第三方庫(kù)
實(shí)戰(zhàn)
運(yùn)算符
類(3)
字典(2)
語(yǔ)句(1)
數(shù)和四則運(yùn)算
語(yǔ)句(2)
文件(2)
MySQL 數(shù)據(jù)庫(kù) (2)
電子表格
迭代器
mongodb 數(shù)據(jù)庫(kù) (1)
特殊方法 (2)
特殊方法 (1)
字符編碼
編寫(xiě)模塊
用 tornado 做網(wǎng)站 (1)
標(biāo)準(zhǔn)庫(kù) (5)
函數(shù)(4)
類(5)
字符串(2)
關(guān)于 Python 的故事
函數(shù)(3)
字符串(4)
處理股票數(shù)據(jù)
常用數(shù)學(xué)函數(shù)和運(yùn)算優(yōu)先級(jí)
字符串(3)
為計(jì)算做準(zhǔn)備
多態(tài)和封裝
類(4)
迭代
語(yǔ)句(3)
錯(cuò)誤和異常 (3)
分析 Hello
Python 安裝
標(biāo)準(zhǔn)庫(kù) (2)
列表(2)
元組

錯(cuò)誤和異常 (1)

錯(cuò)誤和異常 (1)

雖然在前面的學(xué)習(xí)中,已經(jīng)遇到了錯(cuò)誤和異常問(wèn)題,但是一直沒(méi)有很認(rèn)真的研究它?,F(xiàn)在來(lái)近距離觀察錯(cuò)誤和異常。

錯(cuò)誤

Python 中的錯(cuò)誤之一是語(yǔ)法錯(cuò)誤(syntax errors),比如:

>>> for i in range(10)
  File "<stdin>", line 1
    for i in range(10)
                     ^
SyntaxError: invalid syntax

上面那句話因?yàn)槿鄙倜疤?hào):,導(dǎo)致解釋器無(wú)法解釋,于是報(bào)錯(cuò)。這個(gè)報(bào)錯(cuò)行為是由 Python 的語(yǔ)法分析器完成的,并且檢測(cè)到了錯(cuò)誤所在文件和行號(hào)(File "<stdin>", line 1),還以向上箭頭^標(biāo)識(shí)錯(cuò)誤位置(后面缺少:),最后顯示錯(cuò)誤類型。

錯(cuò)誤之二是在沒(méi)有語(yǔ)法錯(cuò)誤之后,會(huì)出現(xiàn)邏輯錯(cuò)誤。邏輯錯(cuò)誤可能會(huì)由于不完整或者不合法的輸入導(dǎo)致,也可能是無(wú)法生成、計(jì)算等,或者是其它邏輯問(wèn)題。

當(dāng) Python 檢測(cè)到一個(gè)錯(cuò)誤時(shí),解釋器就無(wú)法繼續(xù)執(zhí)行下去,于是拋出異常。

異常

看一個(gè)異常(讓 0 做分母了,這是小學(xué)生都相信會(huì)有異常的):

>>> 1/0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: integer division or modulo by zero

當(dāng) Python 拋出異常的時(shí)候,首先有“跟蹤記錄(Traceback)”,還可以給它取一個(gè)更優(yōu)雅的名字“回溯”。后面顯示異常的詳細(xì)信息。異常所在位置(文件、行、在某個(gè)模塊)。

最后一行是錯(cuò)誤類型以及導(dǎo)致異常的原因。

下表中列出常見(jiàn)的異常

異常 描述
NameError 嘗試訪問(wèn)一個(gè)沒(méi)有申明的變量
ZeroDivisionError 除數(shù)為 0
SyntaxError 語(yǔ)法錯(cuò)誤
IndexError 索引超出序列范圍
KeyError 請(qǐng)求一個(gè)不存在的字典關(guān)鍵字
IOError 輸入輸出錯(cuò)誤(比如你要讀的文件不存在)
AttributeError 嘗試訪問(wèn)未知的對(duì)象屬性

為了能夠深入理解,依次舉例,展示異常的出現(xiàn)條件和結(jié)果。

NameError

>>> bar
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'bar' is not defined

Python 中變量需要初始化,即要賦值。雖然不需要像某些語(yǔ)言那樣聲明,但是要賦值先。因?yàn)樽兞肯喈?dāng)于一個(gè)標(biāo)簽,要把它貼到對(duì)象上才有意義。

ZeroDivisionError

>>> 1/0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: integer division or modulo by zero

貌似這樣簡(jiǎn)單的錯(cuò)誤時(shí)不會(huì)出現(xiàn)的,但在實(shí)際情境中,可能沒(méi)有這么容易識(shí)別,所以,依然要小心為妙。

SyntaxError

>>> for i in range(10)
  File "<stdin>", line 1
    for i in range(10)
                     ^
SyntaxError: invalid syntax

這種錯(cuò)誤發(fā)生在 Python 代碼編譯的時(shí)候,當(dāng)編譯到這一句時(shí),解釋器不能講代碼轉(zhuǎn)化為 Python 字節(jié)碼,就報(bào)錯(cuò)。只有改正才能繼續(xù)。所以,它是在程序運(yùn)行之前就會(huì)出現(xiàn)的(如果有錯(cuò))?,F(xiàn)在有不少編輯器都有語(yǔ)法校驗(yàn)功能,在你寫(xiě)代碼的時(shí)候就能顯示出語(yǔ)法的正誤,這多少會(huì)對(duì)編程者有幫助。

IndexError

>>> a = [1,2,3]
>>> a[4]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range

>>> d = {"python":"itdiffer.com"}
>>> d["java"]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'java'

這兩個(gè)都屬于“雞蛋里面挑骨頭”類型,一定得報(bào)錯(cuò)了。不過(guò)在編程實(shí)踐中,特別是循環(huán)的時(shí)候,常常由于循環(huán)條件設(shè)置不合理出現(xiàn)這種類型的錯(cuò)誤。

IOError

>>> f = open("foo")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: [Errno 2] No such file or directory: 'foo'

如果你確認(rèn)有文件,就一定要把路徑寫(xiě)正確,因?yàn)槟悴](méi)有告訴 Python 對(duì)你的 computer 進(jìn)行全身搜索,所以,Python 會(huì)按照你指定位置去找,找不到就異常。

AttributeError

>>> class A(object): pass
... 
>>> a = A()
>>> a.foo
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'A' object has no attribute 'foo'

屬性不存在。這種錯(cuò)誤前面多次見(jiàn)到。

其實(shí),Python 內(nèi)建的異常也不僅僅上面幾個(gè),上面只是列出常見(jiàn)的異常中的幾個(gè)。比如還有:

>>> range("aaa")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: range() integer end argument expected, got str.

總之,如果讀者在調(diào)試程序的時(shí)候遇到了異常,不要慌張,這是好事情,是 Python 在幫助你修改錯(cuò)誤。只要認(rèn)真閱讀異常信息,再用 dir(),help() 或者官方網(wǎng)站文檔、google 等來(lái)協(xié)助,一定能解決問(wèn)題。

處理異常

在一段程序中,為了能夠讓程序健壯,必須要處理異常。舉例:

#!/usr/bin/env Python
# coding=utf-8

while 1:
    print "this is a division program."
    c = raw_input("input 'c' continue, otherwise logout:")
    if c == 'c':
        a = raw_input("first number:")
        b = raw_input("second number:")
        try:
            print float(a)/float(b)
            print "*************************"
        except ZeroDivisionError:
            print "The second number can't be zero!"
            print "*************************"
    else:
        break

運(yùn)行這段程序,顯示如下過(guò)程:

$ python 21601.py 
this is a division program.
input 'c' continue, otherwise logout:c
first number:5
second number:2
2.5
*************************
this is a division program.
input 'c' continue, otherwise logout:c
first number:5
second number:0
The second number can't be zero!
*************************
this is a division program.
input 'c' continue, otherwise logout:d
$

從運(yùn)行情況看,當(dāng)在第二個(gè)數(shù),即除數(shù)為 0 時(shí),程序并沒(méi)有因?yàn)檫@個(gè)錯(cuò)誤而停止,而是給用戶一個(gè)友好的提示,讓用戶有機(jī)會(huì)改正錯(cuò)誤。這完全得益于程序中“處理異?!钡脑O(shè)置,如果沒(méi)有“處理異常”,異常出現(xiàn),就會(huì)導(dǎo)致程序終止。

處理異常的方式之一,使用 try...except...。

對(duì)于上述程序,只看 try 和 except 部分,如果沒(méi)有異常發(fā)生,except 子句在 try 語(yǔ)句執(zhí)行之后被忽略;如果 try 子句中有異常可,該部分的其它語(yǔ)句被忽略,直接跳到 except 部分,執(zhí)行其后面指定的異常類型及其子句。

except 后面也可以沒(méi)有任何異常類型,即無(wú)異常參數(shù)。如果這樣,不論 try 部分發(fā)生什么異常,都會(huì)執(zhí)行 except。

在 except 子句中,可以根據(jù)異?;蛘邉e的需要,進(jìn)行更多的操作。比如:

#!/usr/bin/env Python
# coding=utf-8

class Calculator(object):
    is_raise = False
    def calc(self, express):
        try:
            return eval(express)
        except ZeroDivisionError:
            if self.is_raise:
                print "zero can not be division."
            else:
                raise

在這里,應(yīng)用了一個(gè)函數(shù) eval(),它的含義是:

eval(...)
    eval(source[, globals[, locals]]) -> value

    Evaluate the source in the context of globals and locals.
    The source may be a string representing a Python expression
    or a code object as returned by compile().
    The globals must be a dictionary and locals can be any mapping,
    defaulting to the current globals and locals.
    If only globals is given, locals defaults to it.

例如:

>>> eval("3+5")
8

另外,在 except 子句中,有一個(gè) raise,作為單獨(dú)一個(gè)語(yǔ)句。它的含義是將異常信息拋出。并且,except 子句用了一個(gè)判斷語(yǔ)句,根據(jù)不同的情況確定走不同分支。

if __name__ == "__main__":
    c = Calculator()
    print c.calc("8/0")

這時(shí)候 is_raise = False,則會(huì):

$ python 21602.py 
Traceback (most recent call last):
  File "21602.py", line 17, in <module>
    print c.calc("8/0")
  File "21602.py", line 8, in calc
    return eval(express)
  File "<string>", line 1, in <module>
ZeroDivisionError: integer division or modulo by zero

如果將 is_raise 的值改為 True,就是這樣了:

if __name__ == "__main__":
    c = Calculator()
    c.is_raise = True    #通過(guò)實(shí)例屬性修改
    print c.calc("8/0")

運(yùn)行結(jié)果:

$ python 21602.py 
zero can not be division.
None

最后的 None 是 c.calc("8/0")的返回值,因?yàn)橛?print c.calc("8/0"),所以被打印出來(lái)。


總目錄   |   上節(jié):生成器   |   下節(jié):錯(cuò)誤和異常(2)

如果你認(rèn)為有必要打賞我,請(qǐng)通過(guò)支付寶:qiwsir@126.com,不勝感激。