首頁 >後端開發 >Python教學 >Python 2.7基礎教學之:錯誤與異常

Python 2.7基礎教學之:錯誤與異常

黄舟
黄舟原創
2016-12-24 17:13:591701瀏覽

.. _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 "", line 1, in ?

       while True print 'Hello world'

 xError: invalid syntax

The parser repeats the offending line and displays a little 'arrow ' pointing at

the earliest point in the line where the error was detected.  The error is

caused 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 you

know 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 the

following example, which asks the user for input until a valid integer has been

entered, 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 specify

handlers for different exceptions.  At most one handler will be executed.​​. not

in other handlers of the same :keyword:`try` statement.  An except clause may

name 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 incob​​ion s bound to an exception instance with the arguments stored incob​​ion, 分析🠅nce .

:meth:`__str__` so the arguments can be printed directly without having to

reference ``.args``.

在異常名(列表)之後,也可以為except 子句指定一個變數。這個變數綁定於

一個異常實例,它儲存在 ``instance.args`` 的參數中。為了方便起見,異常實例

定義了 :meth:`__str__` ,這樣就可以直接訪問過打印參數而不必引用

``.args`` 。 

One may also instantiate an exception first before raising it and add any

attributes 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

   ...

  

   ('spam', 'eggs')

= 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 the

try 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 specified

exception to occur. For example:

程式設計師可以用:keyword:`raise` 語句強制指定的例外發生。例如::

   >>> raise NameError('HiThere')

   Traceback (most recent call last):

     File "", line 1. ment to :keyword:`raise` indicates the exception to be raised.

This must be either an exception instance or an exception class (a class that

derives from :class:`ception`).

: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 "", line 2, in ?

     File "", line 2, in ?

     File "", line 2, in ?

.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 "", line 1, in ?

   __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 is

to create a base class for exceptions defined by that module, and subclass that

to 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 "", line 2, in ?

   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 "", line 1, in ?

     File "", line 1, 在 ?

  TypeError: unsupported operand type (s) for /: 'str' and 'str'

As you can see, the :keyword:`finally` clause is executed in any event.  The

:exc:`TypeError` raised by dividing tnot strings handled by the

:keyword:`except` clause and therefore re-raised after the :keyword:`finally`

clause has been executed.

如你所見, :`keyword: `` 子句在任何情況下都會執

行。 :exc:`TypeError`

在兩個字串相除的時候拋出,未被:keyword:`except` 子句捕獲,因此在

:keyword:`finally` 子句執行完畢後重新拋出。

In real world applications, the :keyword:`finally` clause is useful for

releasing external resources (such as files or network connections), regardlesss waso

的應用程式中, :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 provide

predefined clean-up actions will indicate this in their documentation.

語句執行後,檔案*f* 總是會被關閉,即使是在處理文件中的資料時出錯也一樣。

其它物件是否提供了預先定義的清理行為要查看它們的文件。 

 以上是Python 2.7基礎教學之:錯誤與異常的內容,更多相關內容請關注PHP中文網(www.php.cn)!


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