目錄
8.1 Syntax Errors
8.2 Exceptions
8.3 Handling Exceptions
8.4 Raising Exceptions
8.5 User-defined Exception
8.6 Defining Clean-up Actions
8.7 Predefined Clean-up Actions
首頁 後端開發 Python教學 Python兩種錯誤類型的介紹

Python兩種錯誤類型的介紹

Jul 23, 2017 pm 02:06 PM
python

到現在為止都沒有過多介紹錯誤訊息,但是已經在一些範例中使用過錯誤訊息。 Python至少有兩種類型的錯誤:語法錯誤以及異常

8.1 Syntax Errors

語法錯誤,也稱為解析錯誤,是Python初學者常抱怨的問題。

>>> while True print('Hello world')
  File "<stdin>", line 1while True print(&#39;Hello world&#39;)                   ^SyntaxError: invalid syntax
登入後複製

Python解析器重複列印錯誤行,並且展示一個小箭頭,箭頭指向錯誤行中錯誤最早被偵測到的位置。錯誤由箭頭前面的語句導致(至少偵測到是這樣的):以上範例中,錯誤在print()函數被偵測到,因為在它之前的冒號:缺失了。檔案名稱和行號也被印出來,當程式來自腳本時可以方便定位問題。

8.2 Exceptions

即使語句或表達式在語法上是正確的,但是在執行的時候也可能會發生錯誤。在執行期間偵測到的問題叫做異常,異常不是絕對的致命錯誤:接下來會介紹如何在Python中處理異常。然而大多數異常都不會被程式處理,它們最終會成為錯誤訊息,展示如下:

>>> 10 * (1/0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>ZeroDivisionError: division by zero>>> 4 + spam*3Traceback (most recent call last):
  File "<stdin>", line 1, in <module>NameError: name &#39;spam&#39; is not defined>>> &#39;2&#39; + 2Traceback (most recent call last):
  File "<stdin>", line 1, in <module>TypeError: Can&#39;t convert &#39;int&#39; object to str implicitly
登入後複製

最後一行錯誤訊息指出發生了什麼。異常有不同類型,類型也作為錯誤訊息的一部分列印出來:上述範例中的類型有除零異常ZeroDivisionError, 名字異常NameError 以及類型異常TypeError。作為異常類型打印的字串是built-in異常的名字。對於所有built-in異常都是如此,儘管這個約定很有用,但是並不是所有使用者自訂異常都會遵守。標準異常名字是built-in標識符(不是保留字)。

剩餘行基於異常類型展示了詳細的資訊以及異常發生的原因。

前面部分錯誤訊息以堆疊回溯的方式,展示異常發生的上下文資訊。通常在堆疊回溯中列出了原始程式碼行;然而,當程式是從標準輸入中讀取時,不會展示行。

Built-in異常列舉了所有built-in異常以及它們的意義。

8.3 Handling Exceptions

Python程式允許處理指定例外狀況。以下程式要求使用者循環輸入,直到輸入為有效整數停止,但是也可以中斷程式(使用Control-C或其他作業系統支援的手段);注意使用者誘發的中斷會拋出KeyboardInterrupt例外。

while True:try:
        x = int(input("Please enter a number: "))breakexcept ValueError:print("Oops!  That was no valid number.  Try again...")
登入後複製

try語句的執行順序為:

  • 首先,執行在tryexcept之間的try子句

  • 如果沒有例外發生,跳過except子句try語句執行完畢

  • 如果try子句執行期間有例外發生,則該子句內剩餘語句被跳過。接下來如果拋出的異常類型可以與關鍵字except後的異常匹配,那麼except子句執行,接著繼續執行try語句後的語句。

  • 如果異常發生但是沒有匹配到except後的異常,那麼異常拋到外層try語句;如果異常沒有處理,該異常成為未處理異常,導致程式終止並且像上述範例一樣列印資訊。

一個try語句可以有多個except子句,為不同的例外指定處理方法。至多只有一個except子句會被執行。處理程序只會處理發生在對應try子句中的異常,而不會處理發生在同一try語句中其他處理程序中的異常。一個except子句可以使用括號的元組列出多個異常,就像這樣:

... except (RuntimeError, TypeError, NameError):
...     pass
登入後複製

except子句中的類別可以匹配類型是其子類別或它自己類型的異常(但反過來不行,except子句中的子類別不會符合父類別異常)。例如以下程式碼會依序列印B, C, D:

class B(Exception):passclass C(B):passclass D(C):passfor cls in [B, C, D]:try:raise cls()except D:print("D")except C:print("C")except B:print("B")
登入後複製

注意以上的except子句若反過來寫(except B在前),那麼將會印出B, B, B ——第一個except子句的匹配被觸發。

最後一個except子句可以省略異常名字作為萬用字元。因為這樣做會隱藏其他的真實程式錯誤,所以所有要謹慎使用。也可以用來列印錯誤訊息並且重新拋出(允許呼叫者處理例外):

import systry:
    f = open(&#39;myfile.txt&#39;)
    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語句有一個可選的else子句,該子句只能出現在所有except子句之後。若要求try子句沒有拋出例外時必須執行一段程式碼,使用else子句很有用(譯註:else子句會被return, break, continue跳過)。例如:

for arg in sys.argv[1:]:try:
        f = open(arg, &#39;r&#39;)except OSError:print(&#39;cannot open&#39;, arg)else:print(arg, &#39;has&#39;, len(f.readlines()), &#39;lines&#39;)
        f.close()
登入後複製

使用 else 子句比在 try 子句中附加代码要好,因为这样可以避免 try ... except 意外的捕获的本不属于它们保护的那些代码抛出的异常。

异常发生时,可以携带与之关联的值,也称作异常参数。异常参数是否可以存在以及其类型取决于异常类型。

except子句可以在异常名字后指定变量。该变量绑定到异常实例,异常参数存储在instance.args属性中。方便起见,异常实例定义了__str__()以便异常参数可以直接打印,而不是使用.args引用。也可以首先实例化异常,并在抛出它之前加入任何想要的参数:

>>> try:
...     raise Exception(&#39;spam&#39;, &#39;eggs&#39;)
... except Exception as inst:
...     print(type(inst))    # the exception instance...     print(inst.args)     # arguments stored in .args...     print(inst)          # __str__ allows args to be printed directly,...                          # but may be overridden in exception subclasses...     x, y = inst.args     # unpack args...     print(&#39;x =&#39;, x)
...     print(&#39;y =&#39;, y)
...<class &#39;Exception&#39;>(&#39;spam&#39;, &#39;eggs&#39;)
(&#39;spam&#39;, &#39;eggs&#39;)
x = spam
y = eggs
登入後複製

对于未处理异常来说,如果它有参数,那么参数将在错误信息的后面部分(详细信息部分)打印。

异常处理程序不仅仅会处理即时发生在try子句中的异常,还会处理try子句中直接或者间接调用的函数中发生的异常。例如:

>>> def this_fails():
...     x = 1/0...>>> try:
...     this_fails()
... except ZeroDivisionError as err:
...     print(&#39;Handling run-time error:&#39;, err)
...
Handling run-time error: division by zero
登入後複製

8.4 Raising Exceptions

raise语句允许程序员强制发生异常。例如:

>>> raise NameError(&#39;HiThere&#39;)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>NameError: HiThere
登入後複製

raise的唯一参数指定要抛出的异常。参数必须是异常实例或者异常类(继承自Exception类的子类)。如果参数是异常类型,会隐式使用无参方式调用异常的构造器初始化一个异常实例:

raise ValueError  # shorthand for &#39;raise ValueError()&#39;
登入後複製

如果需要捕获异常但是不处理,一种更简单形式的raise语句允许重新抛出这个异常:

>>> try:
...     raise NameError(&#39;HiThere&#39;)
... except NameError:
...     print(&#39;An exception flew by!&#39;)
...     raise...
An exception flew by!Traceback (most recent call last):
  File "<stdin>", line 2, in <module>NameError: HiThere
登入後複製

8.5 User-defined Exception

程序中可以通过创建新异常类的方式提出自己的异常(参见Classes获取Python类的更多信息)。异常必须直接或者间接继承自Exception类。

自定义异常类拥有其他类的功能,但通常需要保持其简洁性,只提供几个供异常处理程序提取错误信息的属性。需要创建一个抛出若干不同错误的模块时,比较好的实践是,为定义在这个模块中的异常创建父类,由子类创建对应不同错误的具体异常:

class Error(Exception):"""Base class for exceptions in this module."""passclass 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 = expressionself.message = messageclass TransitionError(Error):"""Raised when an operation attempts a state transition that&#39;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 = previousself.next = nextself.message = message
登入後複製

与标准异常类类似,大多数异常的名字都以"Error"结尾。

许多标准模块都定义了自己的异常,这些异常对应模块中定义的函数中可能发生的错误。更多信息参考Classes。

8.6 Defining Clean-up Actions

try语句有可选的在任何情况下都会执行的子句,可用于定义清理动作。例如:

>>> try:
...     raise KeyboardInterrupt... finally:
...     print(&#39;Goodbye, world!&#39;)
...
Goodbye, world!KeyboardInterruptTraceback (most recent call last):
  File "<stdin>", line 2, in <module>
登入後複製

无论是否有异常发生,finally子句在离开try语句之前总是会执行。当try子句中有异常发生并且没有被except子句处理(或者异常发生在except子句或else子句),finally子句执行之后,这些异常会重新抛出。当try语句的其他子句通过break, continue或者return语句离开时,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.0executing 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 <module>
  File "<stdin>", line 3, in divideTypeError: unsupported operand type(s) for /: &#39;str&#39; and &#39;str&#39;
登入後複製

正如所见的那样,finally子句在任何情况下都会执行。两个字符串相除产生的TypeError异常没有被except子句处理,因此在finally子句执行完毕之后被重新抛出。

在实践应用中,finally子句用来释放外部资源(比如文件和网络连接),不论资源的使用是否成功。

8.7 Predefined Clean-up Actions

一些对象定义了标准的清理动作,当不再需要这些对象时,会执行清理动作,而不论使用对象的操作是否成功。以下示例读取文件并打印内容到显示器:

for line in open("myfile.txt"):print(line, end="")
登入後複製

这段代码的问题是:当代码执行完毕后,文件会保留打开状态一段不确定的时间。这在简单的脚本中不是什么大问题,但是在大型的应用程序中会出问题。with语句使得像文件一样的对象可以被立即准确回收。

with open("myfile.txt") as f:for line in f:print(line, end="")
登入後複製

语句执行后,即使在执行代码时遇到问题,文件f总是会被关闭。像文件一样提供预定义清理动作的对象会在其说明文档中指示这点。

以上是Python兩種錯誤類型的介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

PHP和Python:解釋了不同的範例 PHP和Python:解釋了不同的範例 Apr 18, 2025 am 12:26 AM

PHP主要是過程式編程,但也支持面向對象編程(OOP);Python支持多種範式,包括OOP、函數式和過程式編程。 PHP適合web開發,Python適用於多種應用,如數據分析和機器學習。

在PHP和Python之間進行選擇:指南 在PHP和Python之間進行選擇:指南 Apr 18, 2025 am 12:24 AM

PHP適合網頁開發和快速原型開發,Python適用於數據科學和機器學習。 1.PHP用於動態網頁開發,語法簡單,適合快速開發。 2.Python語法簡潔,適用於多領域,庫生態系統強大。

PHP和Python:深入了解他們的歷史 PHP和Python:深入了解他們的歷史 Apr 18, 2025 am 12:25 AM

PHP起源於1994年,由RasmusLerdorf開發,最初用於跟踪網站訪問者,逐漸演變為服務器端腳本語言,廣泛應用於網頁開發。 Python由GuidovanRossum於1980年代末開發,1991年首次發布,強調代碼可讀性和簡潔性,適用於科學計算、數據分析等領域。

Python vs. JavaScript:學習曲線和易用性 Python vs. JavaScript:學習曲線和易用性 Apr 16, 2025 am 12:12 AM

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

vs code 可以在 Windows 8 中運行嗎 vs code 可以在 Windows 8 中運行嗎 Apr 15, 2025 pm 07:24 PM

VS Code可以在Windows 8上運行,但體驗可能不佳。首先確保系統已更新到最新補丁,然後下載與系統架構匹配的VS Code安裝包,按照提示安裝。安裝後,注意某些擴展程序可能與Windows 8不兼容,需要尋找替代擴展或在虛擬機中使用更新的Windows系統。安裝必要的擴展,檢查是否正常工作。儘管VS Code在Windows 8上可行,但建議升級到更新的Windows系統以獲得更好的開發體驗和安全保障。

sublime怎麼運行代碼python sublime怎麼運行代碼python Apr 16, 2025 am 08:48 AM

在 Sublime Text 中運行 Python 代碼,需先安裝 Python 插件,再創建 .py 文件並編寫代碼,最後按 Ctrl B 運行代碼,輸出會在控制台中顯示。

visual studio code 可以用於 python 嗎 visual studio code 可以用於 python 嗎 Apr 15, 2025 pm 08:18 PM

VS Code 可用於編寫 Python,並提供許多功能,使其成為開發 Python 應用程序的理想工具。它允許用戶:安裝 Python 擴展,以獲得代碼補全、語法高亮和調試等功能。使用調試器逐步跟踪代碼,查找和修復錯誤。集成 Git,進行版本控制。使用代碼格式化工具,保持代碼一致性。使用 Linting 工具,提前發現潛在問題。

vscode在哪寫代碼 vscode在哪寫代碼 Apr 15, 2025 pm 09:54 PM

在 Visual Studio Code(VSCode)中編寫代碼簡單易行,只需安裝 VSCode、創建項目、選擇語言、創建文件、編寫代碼、保存並運行即可。 VSCode 的優點包括跨平台、免費開源、強大功能、擴展豐富,以及輕量快速。

See all articles