您的位置:首页 > 编程语言 > Python开发

初学python(对比java语言不同) 第十篇

2016-04-14 10:07 330 查看
Java 中 异常处理使用try{...}catch(Except e){...}finally{...} 

Python 错误和异常

语法错误,或者称之为解析错误,语法分析器指出了出错的一行,并且在最先找到的错误的位置标记了一个小小的’箭头’。错误是由箭头前面 的标记引起的(至少检测到是这样的)语法错误,或者称之为解析错误。

异常即使一条语句或表达式在语法上是正确的,在运行它的时候,也有可能发生错误。在执行期间检测到的错误被称为异常并且程序不会无条件地崩溃,而大多数异常都不会被程序处理。

>>> 10 * (1/0)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
ZeroDivisionError: integer division or modulo 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: cannot concatenate 'str' and 'int' objects


错误信息的前面部分以堆栈回溯的形式显示了异常发生的上下文。通常调用栈里会包含源代码的行信息,但是来自标准输入的源码不会显示行信息。

内置的异常 列出了内置的异常以及它们的含义。

处理异常 可以通过编程来选择处理部分异常。看一下下面的例子,它会一直要求用户输入直到输入一个合法的整数为止,但允许用户中断这个程序(使用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..."


Try语句按以下方式工作。

1 首先,执行try子句(try和except关键字之间的语句)。

2 如果未发生任何异常,忽略except子句且try语句执行完毕。

3 如果在try子句执行过程中发生异常,跳过该子句的其余部分。如果异常的类型与except关键字后面的异常名匹配, 则执行except子句,然后继续执行try语句之后的代码。

4 如果异常的类型与except关键字后面的异常名不匹配,它将被传递给上层的try语句;如果没有找到处理这个异常的代码,它就成为一个未处理异常,程序会终止运行并显示一条如上所示的信息。

Try语句可能有多个异常子句,用来指定多个不同的异常。不过至多只有一个处理程序将被执行。处理程序只处理发生在相应try子句中的异常,不会处理同一个try子句的其他处理程序中发生的异常。一个except子句可以用带括号的元组列出多个异常的名字。

... except (RuntimeError, TypeError, NameError):
...     pass


Java7也开始支持多异常处理 catch(IOException | SQLException | Exception ex){...}

最后一个 except 子句可以省略异常名称,以当作通配符使用。使用这种方式要特别小心,因为它会隐藏一个真实的程序错误!它还可以用来打印一条错误消息,然后重新引发异常 (让调用者也去处理这个异常)

import sys
try:
f = open('myfile.txt')
s = f.readline()
i = int(s.strip())
except IOError as e:
print "I/O error({0}): {1}".format(e.errno, e.strerror)
except ValueError:
print "Could not convert data to an integer."
except:
print "Unexpected error:", sys.exc_info()[0]
raise

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()

使用else子句比把额外的代码放在try子句中要好,因为它可以避免意外捕获不是由try ... except语句保护的代码所引发的异常。当异常发生时,它可能带有相关数据,也称为异常的参数。参数的有无和类型取决于异常的类型。

引发异常 raise语句允许程序员强行引发一个指定的异常。

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


用户定义的异常

程序可以通过创建新的异常类来命名自己的异常。异常通常应该继承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!'

在此示例中,Exception默认的__init__()被覆盖了。新的行为简单地创建了value属性。这将替换默认的创建args属性的行为。

异常类可以像其他类一样做任何事情,但是通常都会比较简单,只提供一些属性以允许异常处理程序获取错误相关的信息。创建一个能够引发几种不同错误的模块时,一个通常的做法是为该模块定义的异常创建一个基类,然后基于这个基类为不同的错误情况创建特定的子类。

定义清理操作

Try语句有另一个可选的子句,目的在于定义必须在所有情况下执行的清理操作。

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

不管有没有发生异常,在离开try语句之前总是会执行finally子句。当try子句中发生了一个异常,并且没有except字句处理(或者异常发生在try或else子句中),在执行完finally子句后将重新引发这个异常。try语句由于break、contine或return语句离开时,同样会执行finally子句。

清理操作的预定义

有些对象定义了在不需要该对象时的标准清理操作,无论该对象的使用是成功还是失败。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息