亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

?? ??? ??
Python是什么? Python 3 教程 Python3 基礎(chǔ)語(yǔ)法 編碼 Python3 基本數(shù)據(jù)類型 Python解釋器 Python 注釋 Python 數(shù)字運(yùn)算 Python 字符串 Python 列表 Python 編程第一步 Python 條件控制 Python 循環(huán) Python 函數(shù) Python 數(shù)據(jù)結(jié)構(gòu) Python 模塊 Python 輸入和輸出 Python 錯(cuò)誤和異常 Python 類 Python 標(biāo)準(zhǔn)庫(kù)概覽 Python Hello World 實(shí)例 Python 數(shù)字求和 Python 平方根 Python 二次方程 Python 計(jì)算三角形的面積 Python 隨機(jī)數(shù)生成 Python 攝氏溫度轉(zhuǎn)華氏溫度 Python 交換變量 Python if 語(yǔ)句 Python 判斷字符串是否為數(shù)字 Python 判斷奇數(shù)偶數(shù) Python 判斷閏年 Python 獲取最大值函數(shù) Python 質(zhì)數(shù)判斷 Python 階乘實(shí)例 Python 九九乘法表 Python 斐波那契數(shù)列 Python 阿姆斯特朗數(shù) Python 十進(jìn)制轉(zhuǎn)二進(jìn)制、八進(jìn)制、十六進(jìn)制 Python ASCII碼與字符相互轉(zhuǎn)換 Python 最大公約數(shù)算法 Python 最小公倍數(shù)算法 Python 簡(jiǎn)單計(jì)算器實(shí)現(xiàn) Python 生成日歷 Python 使用遞歸斐波那契數(shù)列 Python 文件 IO Python 字符串判斷 Python 字符串大小寫轉(zhuǎn)換 Python 計(jì)算每個(gè)月天數(shù) Python 獲取昨天日期 Python list 常用操作 Python3 實(shí)例
??

Python 錯(cuò)誤和異常


作為Python初學(xué)者,在剛學(xué)習(xí)Python編程時(shí),經(jīng)常會(huì)看到一些報(bào)錯(cuò)信息,在前面我們沒有提及,這章節(jié)我們會(huì)專門介紹。

Python有兩種錯(cuò)誤很容易辨認(rèn):語(yǔ)法錯(cuò)誤和異常。

語(yǔ)法錯(cuò)誤

Python 的語(yǔ)法錯(cuò)誤或者稱之為解析錯(cuò),是初學(xué)者經(jīng)常碰到的,如下實(shí)例

>>> while True print('Hello world')
  File "<stdin>", line 1, in ?
    while True print('Hello world')
                   ^
SyntaxError: invalid syntax

這個(gè)例子中,函數(shù) print() 被檢查到有錯(cuò)誤,是它前面缺少了一個(gè)冒號(hào)(:)。

語(yǔ)法分析器指出了出錯(cuò)的一行,并且在最先找到的錯(cuò)誤的位置標(biāo)記了一個(gè)小小的箭頭。

異常

即便Python程序的語(yǔ)法是正確的,在運(yùn)行它的時(shí)候,也有可能發(fā)生錯(cuò)誤。運(yùn)行期檢測(cè)到的錯(cuò)誤被稱為異常。

大多數(shù)的異常都不會(huì)被程序處理,都以錯(cuò)誤信息的形式展現(xiàn)在這里:

>>> 10 * (1/0)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ZeroDivisionError: division by zero
>>> 4 + spam*3
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
NameError: name 'spam' is not defined
>>> '2' + 2
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: Can't convert 'int' object to str implicitly

異常以不同的類型出現(xiàn),這些類型都作為信息的一部分打印出來: 例子中的類型有 ZeroDivisionError,NameError 和 TypeError。

錯(cuò)誤信息的前面部分顯示了異常發(fā)生的上下文,并以調(diào)用棧的形式顯示具體信息。

異常處理

以下例子中,讓用戶輸入一個(gè)合法的整數(shù),但是允許用戶中斷這個(gè)程序(使用 Control-C 或者操作系統(tǒng)提供的方法)。用戶中斷的信息會(huì)引發(fā)一個(gè) KeyboardInterrupt 異常。

>>> while True:
        try:
            x = int(input("Please enter a number: "))
            break
        except ValueError:
            print("Oops!  That was no valid number.  Try again   ")
   

try語(yǔ)句按照如下方式工作;

  • 首先,執(zhí)行try子句(在關(guān)鍵字try和關(guān)鍵字except之間的語(yǔ)句)
  • 如果沒有異常發(fā)生,忽略except子句,try子句執(zhí)行后結(jié)束。
  • 如果在執(zhí)行try子句的過程中發(fā)生了異常,那么try子句余下的部分將被忽略。如果異常的類型和 except 之后的名稱相符,那么對(duì)應(yīng)的except子句將被執(zhí)行。最后執(zhí)行 try 語(yǔ)句之后的代碼。
  • 如果一個(gè)異常沒有與任何的except匹配,那么這個(gè)異常將會(huì)傳遞給上層的try中。

一個(gè) try 語(yǔ)句可能包含多個(gè)except子句,分別來處理不同的特定的異常。最多只有一個(gè)分支會(huì)被執(zhí)行。

處理程序?qū)⒅会槍?duì)對(duì)應(yīng)的try子句中的異常進(jìn)行處理,而不是其他的 try 的處理程序中的異常。

一個(gè)except子句可以同時(shí)處理多個(gè)異常,這些異常將被放在一個(gè)括號(hào)里成為一個(gè)元組,例如:

    except (RuntimeError, TypeError, NameError):
        pass

最后一個(gè)except子句可以忽略異常的名稱,它將被當(dāng)作通配符使用。你可以使用這種方法打印一個(gè)錯(cuò)誤信息,然后再次把異常拋出。

import sys

try:
    f = open('myfile.txt')
    s = f.readline()
    i = int(s.strip())
except OSError as err:
    print("OS error: {0}".format(err))
except ValueError:
    print("Could not convert data to an integer.")
except:
    print("Unexpected error:", sys.exc_info()[0])
    raise

try except 語(yǔ)句還有一個(gè)可選的else子句,如果使用這個(gè)子句,那么必須放在所有的except子句之后。這個(gè)子句將在try子句沒有發(fā)生任何異常的時(shí)候執(zhí)行。例如:

for arg in sys.argv[1:]:
    try:
        f = open(arg, 'r')
    except IOError:
        print('cannot open', arg)
    else:
        print(arg, 'has', len(f.readlines()), 'lines')
        f.close()

使用 else 子句比把所有的語(yǔ)句都放在 try 子句里面要好,這樣可以避免一些意想不到的、而except又沒有捕獲的異常。

異常處理并不僅僅處理那些直接發(fā)生在try子句中的異常,而且還能處理子句中調(diào)用的函數(shù)(甚至間接調(diào)用的函數(shù))里拋出的異常。例如:

>>> def this_fails():
        x = 1/0
   
>>> try:
        this_fails()
    except ZeroDivisionError as err:
        print('Handling run-time error:', err)
   
Handling run-time error: int division or modulo by zero

拋出異常

Python 使用 raise 語(yǔ)句拋出一個(gè)指定的異常。例如:

>>> raise NameError('HiThere')
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
NameError: HiThere

raise 唯一的一個(gè)參數(shù)指定了要被拋出的異常。它必須是一個(gè)異常的實(shí)例或者是異常的類(也就是 Exception 的子類)。

如果你只想知道這是否拋出了一個(gè)異常,并不想去處理它,那么一個(gè)簡(jiǎn)單的 raise 語(yǔ)句就可以再次把它拋出。

>>> try:
        raise NameError('HiThere')
    except NameError:
        print('An exception flew by!')
        raise
   
An exception flew by!
Traceback (most recent call last):
  File "<stdin>", line 2, in ?
NameError: HiThere

用戶自定義異常

你可以通過創(chuàng)建一個(gè)新的exception類來?yè)碛凶约旱漠惓?。異常?yīng)該繼承自 Exception 類,或者直接繼承,或者間接繼承,例如:

>>> class MyError(Exception):
        def __init__(self, value):
            self.value = value
        def __str__(self):
            return repr(self.value)
   
>>> try:
        raise MyError(2*2)
    except MyError as e:
        print('My exception occurred, value:', e.value)
   
My exception occurred, value: 4
>>> raise MyError('oops!')
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
__main__.MyError: 'oops!'

在這個(gè)例子中,類 Exception 默認(rèn)的 __init__() 被覆蓋。

當(dāng)創(chuàng)建一個(gè)模塊有可能拋出多種不同的異常時(shí),一種通常的做法是為這個(gè)包建立一個(gè)基礎(chǔ)異常類,然后基于這個(gè)基礎(chǔ)類為不同的錯(cuò)誤情況創(chuàng)建不同的子類:

class Error(Exception):
    """Base class for exceptions in this module."""
    pass

class InputError(Error):
    """Exception raised for errors in the input.

    Attributes:
        expression -- input expression in which the error occurred
        message -- explanation of the error
    """

    def __init__(self, expression, message):
        self.expression = expression
        self.message = message

class TransitionError(Error):
    """Raised when an operation attempts a state transition that's not
    allowed.

    Attributes:
        previous -- state at beginning of transition
        next -- attempted new state
        message -- explanation of why the specific transition is not allowed
    """

    def __init__(self, previous, next, message):
        self.previous = previous
        self.next = next
        self.message = message

大多數(shù)的異常的名字都以"Error"結(jié)尾,就跟標(biāo)準(zhǔn)的異常命名一樣。


定義清理行為

try 語(yǔ)句還有另外一個(gè)可選的子句,它定義了無論在任何情況下都會(huì)執(zhí)行的清理行為。 例如:

>>> try:
        raise KeyboardInterrupt
	finally:
        print('Goodbye, world!')
   
Goodbye, world!
KeyboardInterrupt

以上例子洪不管try子句里面有沒有發(fā)生異常,finally子句都會(huì)執(zhí)行。

如果一個(gè)異常在 try 子句里(或者在 except 和 else 子句里)被拋出,而又沒有任何的 except 把它截住,那么這個(gè)異常會(huì)在 finally 子句執(zhí)行后再次被拋出。

下面是一個(gè)更加復(fù)雜的例子(在同一個(gè) try 語(yǔ)句里包含 except 和 finally 子句):

>>> def divide(x, y):
        try:
            result = x / y
        except ZeroDivisionError:
            print("division by zero!")
        else:
            print("result is", result)
        finally:
            print("executing finally clause")
   
>>> divide(2, 1)
result is 2.0
executing finally clause
>>> divide(2, 0)
division by zero!
executing finally clause
>>> divide("2", "1")
executing finally clause
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "<stdin>", line 3, in divide
TypeError: unsupported operand type(s) for /: 'str' and 'str'

預(yù)定義的清理行為

一些對(duì)象定義了標(biāo)準(zhǔn)的清理行為,無論系統(tǒng)是否成功的使用了它,一旦不需要它了,那么這個(gè)標(biāo)準(zhǔn)的清理行為就會(huì)執(zhí)行。

這面這個(gè)例子展示了嘗試打開一個(gè)文件,然后把內(nèi)容打印到屏幕上:

for line in open("myfile.txt"):
    print(line, end="")

以上這段代碼的問題是,當(dāng)執(zhí)行完畢后,文件會(huì)保持打開狀態(tài),并沒有被關(guān)閉。

關(guān)鍵詞 with 語(yǔ)句就可以保證諸如文件之類的對(duì)象在使用完之后一定會(huì)正確的執(zhí)行他的清理方法:

with open("myfile.txt") as f:
    for line in f:
        print(line, end="")

以上這段代碼執(zhí)行完畢后,就算在處理過程中出問題了,文件 f 總是會(huì)關(guān)閉。

?? ??: ?? ??: