.. _tut-errors:
==================================
Errors and Exceptions 錯誤和異常
==================================
Until now error messages haven't been more than mentioned , but if you have tried
out the examples you have probably seen some. There are (at least) two
distinguishable kinds of errors: *syntax errerr* and *exceptions.錯誤訊息,不過在你已經試驗過的那些例子中,
可能已經遇到過一些。 Python 中(至少)有兩種錯誤:語法錯誤和異常
( *syntax errors* and *exceptions* )。
.. _tut-syntaxerrors:
Syntax Errors 語法錯誤
========================
Syntaxerrors, also known as parare==== errors, parare perhaps the most common kind of
complaint you get while you are still learning Python:
語法錯誤,也稱作解釋錯誤,可能是學習Python 的過程中最容易犯的::
print >>> while print >> 'Hello world'
File "
while True print 'Hello world'
xError: invalid syntaxThe parser repeats the offending line and displays a little 'arrow ' pointing atthe earliest point in the line where the error was detected. The error iscaused by (or at least detected at) the token *preceding* the arrow: in the, in the
or excepect the keyword :keyword:`print`, since a colon(``':'``) is missing before it. File name and line number are printed so youknow where to look in case the input came from a came from script.解析器會重複出錯的行,並在行中最早發現的錯誤位置上顯示一個小「箭頭」。錯誤(至少是被偵測到的)就發生在箭頭 *指向* 的位置。範例中的錯誤表現在關鍵字:keyword:`print` 上,因為在它之前少了一個冒號( ``':'`` )。同時也會顯示檔案名稱和行號,這樣你就可以知道錯誤來自哪個腳本,什麼位置。 .. _tut-exceptions:Exceptions.. _tut-exceptions:
Exceptions
==========
Even if a statement or expression is syntactically correct, it may cacement an expression 是. Errors detected during execution
are called *exceptions* and are not unconditionally fatal: you will soon learn
how to handle them in Python programs. as shown here:
即使是在語法上完全正確的語句,嘗試執行它的時候,也有可能會發生錯誤。在
程式運作中偵測出的錯誤稱之為異常,它通常不會導致致命的問題,你很快就會
學到如何在 Python 程式中控制它們。大多數異常不會由程式處理,而是顯示一
個錯誤訊息::
>>> 10 * (1/0)
Traceback (most recent call last):
Traceback (most recent call last):
> , line 1, in ?
ZeroDivisionError: integer division or modulo by zero
>>> 4 + spam*3
Traceback (most recentd
NameError: name 'spam' is not defined
>>> '2' + 2
Traceback Error: cannot concatenate 'str' and 'int' objects
The last line of the error message indicates what happened. Exceptions come in
different types, and the type is printed as part
different types, and the type is printed as part of the message the partsares part 是s part. exc:`ZeroDivisionError`, :exc:`NameError` and :exc:`TypeError`.The string printed as the exception type is the name of the built-in exception🜎 in exceptions, but need not be true
for user-defined exceptions (although it is a useful convention). Standard
exception names are built-in identifiers (not reserved keys. reserved什麼錯誤。異常也有不同的類型,異常類型做為
錯誤訊息的一部分顯示出來:範例中的異常分別為零除錯誤
( :exc:`ZeroDivisionError` ) ,命名錯誤( :exc:`NameError`) 和類型
錯誤(:exc:`TypeError` )。列印錯誤訊息時,異常的類型會作為異常的內建名稱
顯示。對於所有的內建異常都是如此,不過使用者自訂異常就不一定了(儘管這
是一個很有用的約定)。標準異常名是內建的標識(沒有保留關鍵字)。
The rest of the line provides detail based on the type of exception and what
caused it.
這一行後一部分是關於該異常類型的詳細說明,這意味著它的內容依賴於異常類型。
The preceding part of the error message shows the context where the exception
happened, in the form of a stack traceback. In general it contains a stack
t show list ar back backs 可 遊戲 日書 arl show backs 2 月;
standard input.錯誤訊息的前半部以堆疊的形式列出異常發生的位置。通常在堆疊中列出了原始程式碼行,然而,來自標準輸入的原始碼不會顯示出來。 :ref:`bltin-exceptions` lists the built-in exceptions and their meanings.:ref:`bltin-exceptions` 列出了內建異常和它們的含義。 .. _tut-handling:Handling Exceptions 控制異常============================It is possible to write programs that handle selected exceptions. Look at thefollowing example, which asks the user for input until a valid integer has beenentered, but allows the user to interrupt the program (本
whatever the operating system supports); note that a user-generated interruption
is signalled by raising the :exc:`KeyboardInterrupt` exception. :
可以寫出來控制已知的異常。請參閱下例,此範例要求使用者輸入訊息,一直到
得到一個有效的整數為止,而且允許使用者中斷程式(使用:kbd:`Control-C` 或
其它什麼作業系統支援的操作);需要注意的是使用者產生的中斷會拋出
:exc:`KeyboardInterrupt` 例外。 ::
>>> while True:
... try:
... x = int(raw)
... except ValueError : ... print "Oops! That was no valid number. Try again..." ...句按如下方式工作。 * First, the *try clause* (the statement(s) between the :keyword:`try` and :keyword:`except` keywords) 是先在* :keyword:`try` 和:keyword:`except` 關鍵字之間的部分)。 * If no exception occurs, the *except clause* is skipped and execution of the :keyword:`try` statement is finished. 語句執行完畢後就被忽略了。 * If an exception occurs during execution of the try clause, the rest of the clause is skipped. Then if its type matoo the exception named after the executed, and then execution continues after the :keyword:`try` statement. 如果在try 子句執行過程中發生了異常,那麼該子句其餘的部分就會被忽略。 如果異常符合 :keyword:`except` 關鍵字後面指定的異常類型,就執行對應的except子 句。然後繼續執行 :keyword:`try` 語句之後的程式碼。 * If an exception occurs which does not match the exception named in the except clause, it is passed on to outer :keyword:`try state.c. *和 execution stops with a message as shown above. 如果發生了一個異常,except 子句中沒有與之匹配的分支,它就會傳遞到 語句中上一層:keykeyword`try 語句中句。如果最後找不到對應的處理語句,它就成 為一個 *未處理異常* ,終止程式運行,顯示提示訊息。 A :keyword:`try` statement may have more than one except clause, to specifyhandlers for different exceptions. At most one handler will be executed.. not in other handlers of the same :keyword:`try` statement. An except clause mayname multiple exceptions as a parenthesized tuple, for example: 名詞片語可以包含多個子句key: example:``ample: 7: 一個字句)可能包含一個字詞,分別指定處理不同的異常。至多只會有一個分支被執行。異常處理程序只會處理對應的 try 子句中發生的異常,在同一個 :keyword:`try` 語句中,其他子句中發生的異常則不作處
理。一個except子句可以在括號中列出多個異常的名字,例如::
... except (RuntimeError, TypeError, NameError):
... pass
The (s), to serve as a wildcard.
Use this with extreme caution, since it is easy to mask a real programming error
in this way! It 它
the exception (allowing a caller to handle the exception as well):最後一個except 子句可以省略異常名,把它當作一個通配項使用。一定要慎用這種方法,因為它很可能會屏蔽掉真正的程式錯誤,使人無法發現!它也可以用於列印一行錯誤訊息,然後重新拋出例外(可以讓呼叫者更好的處理異常) :: import sys try:try:
s = f.readline()
i = int(s.strip())
except IOError as (errno,))
1}" .format(errno, strerror)
except ValueError:
print "Could not convert data to an integer."
: print _info()[0]
raise
The :keyword:`try` ... :keyword:`except` statement has an optional *else
clause*, which, when present, must follow all except clauses。 if the try clause does not raise an exception. For
example:
:keyword:`try` ... :keyword:`except` 語句可以有一個*else 子句* ,
該子句只能出現在所有except 子句之後。當 try 語句沒有拋出例外時,就需要執行一些程式碼,可以使用
這個子句。例如::
for arg in sys.argv[1:]:
try:
print 'cannot open', arg
else:
print arg, 'has', len(f.readlines()), 'lines'
f.close) (
the :keyword:`try` clause because it avoids accidentally catching an exception
that wasn't raised by the code being protected by the :keyword:`try` ...
:`state:`oception statement.使用:keyword:`else` 子句比在:keyword:`try` 子句中附加程式碼好,因為
這樣可以避免:keyword:`try` ... :keyword:`except` 意外的截獲本來不屬於
它們保護的那些程式碼拋出的異常。
When an exception occurs, it may have an associated value, also known as the
exception's *argument*. The presence and type of the argument depend on the版本
附屬值,作為異常的*參數* 存在。這個參數是否存在、是什麼類型,依賴異常的類型。 The except clause may specify a variable after the exception name (or tuple).The variable is bound to an exception instance with the arguments stored incobion s bound to an exception instance with the arguments stored incobion, 分析🠅nce . :meth:`__str__` so the arguments can be printed directly without having toreference ``.args``.在異常名(列表)之後,也可以為except 子句指定一個變數。這個變數綁定於一個異常實例,它儲存在 ``instance.args`` 的參數中。為了方便起見,異常實例定義了 :meth:`__str__` ,這樣就可以直接訪問過打印參數而不必引用``.args`` 。 One may also instantiate an exception first before raising it and add anyattributes to it as desired. :這種做法不受鼓勵。相反,更好的做法是給異常傳遞一個參數(如果要傳遞多個參數,可以傳遞一個元組),把它綁定到 message 屬性。一旦異常發生,它會在拋出前綁定所有指定的屬性。 :: >>> try: ... raise Exception('spam', 'eggs') ... except Exception as inst: ... print type(inst) # the exception instance... print inst.args # arguments stored in .args
... print inst # __str__ allows args to printed directly
... x, y = inst
... x, y = inst not... x, y = inst.
... print 'x =', x ... print ' y =', y ...= eggs
If an exception has an argument, it is printed as the last part ('detail') of
the message for unhandled exceptions.
the message for unhandled exceptions.對於未處理的參數,如果它做作為錯誤訊息的最後一部分(「明細」)列印出來。 Exception handlers don't just handle exceptions if they occur immediately in thetry clause, but also if they occur inside functions that are called (even柄柄書柄 % 詞柄書柄?不只可以處理直接發生在try 子句中的異常,即使是其中(甚至
是間接)呼叫的函數,發生了異常,也一樣可以處理。例如::
>>> def this_fails():
... x = 1/0
...
• try:
... • try:...
ZeroDivisionError as detail: ... print 'Handling run-time error:', detail ... Handling run-time error: int未來 vision or modul-by ions拋出例外===========================The :keyword:`raise` statement allows the programmer to force a specifiedexception to occur. For example:程式設計師可以用:keyword:`raise` 語句強制指定的例外發生。例如:: >>> raise NameError('HiThere') Traceback (most recent call last): File "
:keyword:`raise` 的唯一參數識別。它必需是一個異常實例或
異常類別(繼承自 :class:`Exception` 的類別)。
If you need to determine whether an exception was raised but don't intend to
handle it, a simpler form of the :keyword:`raise` statement allows you to
需要明確一個異常是否拋出,但不想處理它, :keyword:`raise` 語句可以讓你很簡單的重新拋出該異常。 >>> try: ... raise NameError('HiThere') ... except NameError: raise .. . An exception flew by! Traceback (most recent call last): File " File "
.p.
User-defined Exceptions 使用者自訂異常
======================================
Programs may name their own exceptions by creating a new exception class (see
:ref:`tut-classes` for more about Python classes). Exceptions should typically
be derived from the :`ceptions should typically
be derived from the :`ceptc. For
example:
在程式中可以透過建立新的異常類型來命名自己的異常(Python 類別的內容請參
見:ref:`tut-classes` )。異常類別通常應該直接或間接的從
:exc:`Exception` 類別派生,例如::
>>> class MyError(Exception):
... def __init__(self, value. .. self.value = value
... def __str__(self):
...
... raise MyError( 2*2) ... except MyError as e: ... print 'My exception occurred, value:', e.value >> > raise MyError('oops!')Traceback (most recent call last):
File "
__main__.MyError: 'oops!'
__main__.MyError: 'oops!'
__main__.MyError: 'oops!'
__main__.MyError: 'oops!'
__main__.MyError: 'oops!'🟎 :`Exception` has been
overridden. The new behavior simply creates the *value* attribute. This
replaces the default behavior of creating the *args
replaces the default behavior of creating the *args* at`h.的:meth:`__init__` 被覆蓋。新的方式簡單的建立
value 屬性。這就替換了原來創建 *args* 屬性的方式。
Exception classes can be defined which do anything any other class can do, but
are usually kept simple, often only offering a number of attributes that allow
ion for stracted heion tracted not.creating a module that can raise several distinct errors, a common practice isto create a base class for exceptions defined by that module, and subclass thatto create specific exception classes for different error conditions:異常類中可以定義任何其它類中可以定義的東西,但是通常為了保持簡單,只在其中加入幾個屬性信息,以供異常處理句柄提取。如果一個新建立的模組中需要拋出幾種不同的錯誤時,一個通常的作法是為該模組定義一個異常基類,然後針對不同的錯誤類型派生出對應的異常子類。 :: class Error(Exception): """Base class for exceptions in this module.""" """Exception raised for errors in the input. Attributes: expr -- input expression in which the error occurred """ def __init__(self, expr, msg): self.expr = expr
self.msg = msg class TransitionError(Error): Attributes: prev -- state at beginning of transition -- attempted new state msg -- explanation of why the specific transition is not allowed
self.prev = prev
self.next = 下一個
self.msg = msg
Most exceptions are defined with names that end in "Error," similar to the
naming of standard ex Error”結尾。
Many standard modules define their own exceptions to report errors that may
occur in functions they define. More information on classes is presented in🜎自己的異常,用以報告在他們所定義的函數中可能發生
的錯誤。關於類別的進一步資訊請參見 :ref:`tut-classes` 一章。
.. _tut-cleanup:
Defining Clean-up Actions 定義清理行為
============================== ======================
The :keyword:`try` statement has another optional clause which is intended to
define clean-up actions that must be executed under all circumstances. For
example:
:keyword:`try` 語句還有另一個可選的子句,目的在於定義在任何情況下都一定要執行的功
能。例如::
>>> try:
... raise KeyboardInterrupt
... finally:
world !
Traceback (most recent call last):
File "
KeyboardInterrupt
A *finally clause* is always executed before ving the ? has occurred or not. When an exception has
occurred in the :keyword:`try` clause and has not been handled by an
:keyword:`except` clause (or it has occurred in a :keyword:`except` or
:keyword:`else` clause), it is re-raised after the :keyword:`finally` clause), it is re-raised after the :keyword:`finally` clause finally` cla been executed. The :keyword:`finally` clause is also executed "on the way out"
when any other clause of the :keyword:`try` statement is left via a words :`continue` or :keyword:`return` statement. A more
complicated example (having :keyword:`except` and :keyword:`finally` clauses in
the samestate :keyword:`finally` clauses in
the samestate. Python 2.5):
不管有沒有發生異常, *finally 子句* 在程式離開:keyword:`try` 後都一定
會被執行。當:keyword:`try` 語句中發生了未被:keyword:`except` 捕獲的
異常(或者它發生在:keyword:`except` 或:keyword:`else` 子句中),在
:keyword:`finally` 子句執行完後它會被重新拋出。 :keyword:`try` 語句經
由 :keyword:`break` ,:keyword:`continue` 或 :keyword:`return` 語句退
出也一樣會執行 :keyword:`finally` 從句。以下是一個更複雜些的例子(在同
一個:keyword:`try` 語句中的:keyword:`except` 和:keyword:`finally`
子句的工作方式與Python 2.5 一樣) ::
>>> def divide(x, y):
... try:
... ... print "division by zero!"
... else:
... print "result is", result
...
>>> divide(2 , 1)
result is 2
executing finally clause
>>> divide(2, 0)
> divide("2", "1") executing finally clause Traceback (most recent call last): File " File "
的應用程式中, :keyword:`finally` 子句用於釋放外部資源(檔案
或網路連線之類的),無論它們的使用過程中是否出錯。
.. _tut-cleanup-with:
Predefined Clean-up Actions 預定義清理行為
============================= ===============================
Some objects define standard clean-up actions to be undertaken when the object
is no longer needed , regardless of whether or not the operation using the object
succeeded or failed. Look at the following example, which tries to open a file
and print its contents to the screen. : ,無論物件操作是否成功,不再需要該物件的時
候就會起作用。以下範例嘗試開啟檔案並把內容列印到螢幕上。 ::
for line in open("myfile.txt"):
print line
The problem with this code is that it leaves the open open for anooter ate🜥 . is not an issue in
simple scripts, but can be a problem for larger applications. The
:keyword:`with` statement allows objects like files to be used in a way thatred ormlehed thempy r. correctly. :
這段程式碼的問題在於在程式碼執行完後沒有立即關閉開啟的檔案。這在簡單的腳本
裡沒什麼,但是大型應用程式就會出問題。 :keyword:`with` 語句使得文件之類的物件可以
確保總是能及時準確地進行清理。 ::
with open("myfile.txt") as f:
for line in f:
print line🎢
After state thestatement, 55 problem was encountered while processing the lines. Other objects which providepredefined clean-up actions will indicate this in their documentation.語句執行後,檔案*f* 總是會被關閉,即使是在處理文件中的資料時出錯也一樣。 其它物件是否提供了預先定義的清理行為要查看它們的文件。 以上是Python 2.7基礎教學之:錯誤與異常的內容,更多相關內容請關注PHP中文網(www.php.cn)!