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 (using Control-C or whatever the operating system supports); note that a user-generated interruption is signalled by raising the KeyboardInterrupt exception.
通过编程可以处理指定的异常。以下的例子重复要求用户输入一个值,直到用户输入的是一个合法的整数为止。不过这个程序允许用户中断程序(使用 Control-C 或者其它操作系统支持的方法)。需要注意的是用户发出的中断会引发一个 KeyboardInterrupt 异常。
>>> while True: ... try: ... x = int(raw_input("Please enter a number: ")) ... break ... except ValueError: ... print "Oops! That was no valid number. Try again..." ...
The try statement works as follows.
try 语句按如下方式工作:
首先,执行 try 子句(在 try 和 except 关键字之间的部分)。
如果没有异常发生, except 子句 在 try 语句执行完毕后就被忽略了。
如果在 try 子句执行过程中发生了异常,那么该子句其余的部分就会被忽略。如果异常匹配于 except 关键字后面指定的异常类型,就执行对应的except子句,忽略try子句的其它部分。然后继续执行try语句之后的代码。
如果发生了一个异常,在 except 子句中没有与之匹配的分支,它就会传递到上一级 try 语句中。如果最终仍找不到对应的处理语句,它就成为一个未处理异常,终止程序运行,显示提示信息。
A try statement may have more than one except clause, to specify handlers for different exceptions. At most one handler will be executed. Handlers only handle exceptions that occur in the corresponding try clause, not in other handlers of the same try statement. An except clause may name multiple exceptions as a parenthesized list, for example:
一个 try 语句可能包含多个 except 子句,分别指定处理不同的异常。至多只会有一个分支被执行。异常处理程序只会处理对应的 try 子句中发生的异常,在同一个 try 语句中,其他子句中发生的异常则不作处理。一个except子句可以在括号中列出多个异常的名字,例如:
... except (RuntimeError, TypeError, NameError): ... pass
The last except clause may omit the exception name(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 can also be used to print an error message and then re-raise the exception (allowing a caller to handle the exception as well):
最后一个 except 子句可以省略异常名,把它当做一个通配项使用。一定要慎用这种方法,因为它很可能会屏蔽掉真正的程序错误,使人无法发现!它也可以用于打印一行错误信息,然后重新抛出异常(可以使调用者更好的处理异常)。
import sys try: f = open('myfile.txt') s = f.readline() i = int(s.strip()) except IOError, (errno, strerror): print "I/O error(%s): %s" % (errno, strerror) except ValueError: print "Could not convert data to an integer." except: print "Unexpected error:", sys.exc_info()[0] raise
The try ... except statement has an optional else clause, which, when present, must follow all except clauses. It is useful for code that must be executed if the try clause does not raise an exception. For example:
try ... except 语句可以带有一个 else 子句, 该子句只能出现在所有 except 子句之后。当 try 语句没有抛出异常时,需要执行一些代码,可以使用这个子句。例如:
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()
The use of the else clause is better than adding additional code to the try clause because it avoids accidentally catching an exception that wasn't raised by the code being protected by the try ... except statement.
使用 else 子句比在 try 子句中附加代码要好,因为这样可以避免 try ... 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 exception type.
发生异常时,可能会有一个附属值,作为异常的参数存在。这个参数是否存在、是什么类型,依赖于异常的类型。
The except clause may specify a variable after the exception name (or list).
The variable is bound to an exception instance with the arguments stored
in instance.args
. For convenience, the exception instance
defines __getitem__ and __str__ so the arguments can
be accessed or printed directly without having to reference .args
.
在异常名(列表)之后,也可以为 except
子句指定一个变量。这个变量绑定于一个异常实例,它存储在
instance.args
的参数中。为了方便起见,异常实例定义了
__getitem__ 和 __str__
,这样就可以直接访问过打印参数而不必引用 .args
。
>>> try: ... raise Exception('spam', 'eggs') ... except Exception, 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 # __getitem__ allows args to be unpacked directly ... print 'x =', x ... print 'y =', y ... <type 'instance'> ('spam', 'eggs') ('spam', 'eggs') x = spam y = eggs
If an exception has an argument, it is printed as the last part (`detail') of 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 indirectly) in the try clause. For example:
异常处理句柄不止可以处理直接发生在 try 子句中的异常,即使是其中(甚至是间接)调用的函数,发生了异常,也一样可以处理。例如:
>>> def this_fails(): ... x = 1/0 ... >>> try: ... this_fails() ... except ZeroDivisionError, detail: ... print 'Handling run-time error:', detail ... Handling run-time error: integer division or modulo