📄 00000007.htm
字号:
<HTML><HEAD> <TITLE>BBS水木清华站∶精华区</TITLE></HEAD><BODY><CENTER><H1>BBS水木清华站∶精华区</H1></CENTER>发信人: yyh (一笑了之), 信区: Linux <BR>标 题: 第八章 错误与例外 <BR>发信站: BBS 水木清华站 (Tue Jun 20 17:06:02 2000) <BR> <BR>第八章 错误与例外 <BR>到现在为止我们只是提到了错误信息而没有详细讨论,如果你运行了前面的例子可能已 <BR>经看到了一些错误信息。至少有两种不同错误:句法错和例外错(exceptions)。 <BR>8.1 句法错 <BR> 句法错也称为语法分析错,是你在学习Python的时候最可能犯的错误。 <BR>><I>>> while 1 print 'Hello world' </I><BR> File "<stdin>", line 1 <BR> while 1 print 'Hello world' <BR> ^ <BR>SyntaxError: invalid syntax <BR>语法分析器重复出错行,并用一个小‘箭头’指向行内最早发现错误的位置。错误是由 <BR>箭头前面的记号引起的(至少是在这里检测到的)。在本例中,错误在关键字print处检 <BR>测到,因为它前面应该有一个冒号(“:”)。错误信息中显示了文件名和行号这样如果 <BR>错误发生在一个脚本文件中你就知道到哪里去找。 <BR>8.2 例外 <BR>即使语句或表达式句法没有问题,在试图运行的时候也可能发生错误。运行时检测到的 <BR>错误叫做例外,这种错误不一定必然是致命的:你很快就会学到如何在Python程序中处 <BR>理例外。然而,多数例外不能被程序处理,这是会产生错误信息,如: <BR>><I>>> 10 * (1/0) </I><BR>Traceback (innermost last): <BR> File "<stdin>", line 1 <BR>ZeroDivisionError: integer division or modulo <BR>><I>>> 4 + spam*3 </I><BR>Traceback (innermost last): <BR> File "<stdin>", line 1 <BR>NameError: spam <BR>><I>>> '2' + 2 </I><BR>Traceback (innermost last): <BR> File "<stdin>", line 1 <BR>TypeError: illegal argument type for built-in operation <BR>错误信息的最后一行显示发生的情况。例外有不同的类型,类型作为错误信息的一部分 <BR>显示:上例中错误的类型有ZeroDivisionError、NameError和TypeError。作为例外类型 <BR>显示的字符串是发生的例外的内置名。这对于所有内置例外成立,但对用户自定义例外 <BR>不一定成立(用户最好能遵守这样的约定)。标准例外名是内置的标识符(不是保留关 <BR>键字)。 <BR>此行的其余部分是错误的细节,其解释依赖于例外类型。错误信息前面的部分以堆栈反 <BR>跟踪的形式显示了发生错误的上下文环境。一般这包含了列出源代码行的一个列出源程 <BR>序行的堆栈反跟踪;然而,它不会显示从标准输入读进的行。 <BR> 库参考手册列出了内置例外和其含义。 <BR>8.3 例外处理 <BR> 可以编程序来处理选定的例外。请看下面的例子,显示一些浮点数的倒数: <BR>><I>>> numbers = [0.3333, 2.5, 0, 10] </I><BR>><I>>> for x in numbers: </I><BR>... print x, <BR>... try: <BR>... print 1.0 / x <BR>... except ZeroDivisionError: <BR>... print '*** has no inverse ***' <BR>... <BR>0.3333 3.00030003 <BR>2.5 0.4 <BR>0 *** has no inverse *** <BR>10 0.1 <BR>try语句是这样工作的: <BR>首先,运行try子句(在try和except之间的语句)。 <BR>如果没有发生例外,跳过except子句,try语句运行完毕。 <BR>如果在try子句中发生了例外错误而且例外错误匹配except后指定的例外名,则跳过try <BR> 子句剩下的部分,执行except子句,然后继续执行try语句后面的程序。 <BR>如果在try子句中发生了例外错误但是例外错误不匹配except后指定的例外名,则此例外 <BR>被传给外层的try语句。如果没有找到匹配的处理程序则此例外称作是未处理例外,程序 <BR>停止运行,显示错误信息。 <BR>try语句可以有多个except子句,为不同的例外指定不同处理。至多只执行一个错误处理 <BR>程序。错误处理程序只处理相应的try子句中发生的例外,如果同try语句中其它的错误 <BR>处理程序中发生例外错误处理程序不会反应。一个except子句可以列出多个例外,写在 <BR>括号里用逗号分开,例如: <BR>... except (RuntimeError, TypeError, NameError): <BR>... pass <BR>最后一个except子句可以省略例外名,作为一个通配项。这种方法要谨慎使用,因为这 <BR>可能会导致程序实际已出错却发现不了。 <BR>try ... except语句有一个可选的else子句,如有的话要放在所有except子句之后。el <BR>se 的意思是没有发生例外,我们可以把try子句中没有发生例外时要做的事情放在这个 <BR>子句里。例如: <BR>for arg in sys.argv[1:]: <BR> try: <BR> f = open(arg, 'r') <BR> except IOError: <BR> print '不能打开', arg <BR> else: <BR> print arg, '有', len(f.readlines()), '行' <BR> f.close() <BR>例外发生时可能伴有一个值,叫做例外的参数。参数是否存在及其类型依赖于例外的类 <BR>型。对于有参数的例外,except在自居可以在例外名(或表)后指定一个变量用来接受 <BR>例外的参数值,如: <BR>><I>>> try: </I><BR>... spam() <BR>... except NameError, x: <BR>... print 'name', x, 'undefined' <BR>... <BR>name spam undefined <BR>有参数的例外未处理时会在错误信息的最后细节部分列出其参数值。 <BR>例外处理程序不仅处理直接产生于try子句中的例外,也可以处理try子句中调用的函数 <BR>(甚至是间接调用的函数)中的例外。如: <BR>><I>>> def this_fails(): </I><BR>... x = 1/0 <BR>... <BR>><I>>> try: </I><BR>... this_fails() <BR>... except ZeroDivisionError, detail: <BR>... print 'Handling run-time error:', detail <BR>... <BR>Handling run-time error: integer division or modulo <BR>8.4 产生例外 <BR>raise语句允许程序员强行产生指定的例外。例如: <BR>><I>>> raise NameError, 'HiThere' </I><BR>Traceback (innermost last): <BR> File "<stdin>", line 1 <BR>NameError: HiThere <BR>raise语句的第一个参数指定要产生的例外的名字。可选的第二参数指定例外的参数。 <BR> <BR>8.5 用户自定义例外 <BR>程序中可以定义自己的例外,只要把一个字符串赋给一个变量即可。例如: <BR>><I>>> my_exc = 'my_exc' </I><BR>><I>>> try: </I><BR>... raise my_exc, 2*2 <BR>... except my_exc, val: <BR>... print 'My exception occurred, value:', val <BR>... <BR>My exception occurred, value: 4 <BR>><I>>> raise my_exc, 1 </I><BR>Traceback (innermost last): <BR> File "<stdin>", line 1 <BR>my_exc: 1 <BR>许多标准模块用这种方法报告自己定义的函数中发生的错误。 <BR>8.6 定义清理动作 <BR> try语句还有另一个finally可选子句,可以用来规定不论出错与否都要执行的动作。 <BR>例如: <BR>><I>>> try: </I><BR>... raise KeyboardInterrupt <BR>... finally: <BR>... print 'Goodbye, world!' <BR>... <BR>Goodbye, world! <BR>Traceback (innermost last): <BR> File "<stdin>", line 2 <BR>KeyboardInterrupt <BR>finally子句不论try子句中是否发生例外都会执行。例外发生时,先执行finally子句然 <BR>后重新提出该例外。当try语句用break或return语句退出时也将执行finally子句。 <BR>要注意的是,try语句有了except子句就不能有finally子句,有了finally子句就不能有 <BR>except 子句,不能同时使用except子句和finally子句。需要的话可以嵌套。 <BR> <BR>-- <BR>※ 来源:·BBS 水木清华站 smth.org·[FROM: 162.105.17.22] <BR><CENTER><H1>BBS水木清华站∶精华区</H1></CENTER></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -