📄 node10.html
字号:
<p> </p> </li> <li>如果所发生的exception在except关键字之后找不到相对应的类型时,系统会将这个类型传给外面一层的 <tt class="keyword">try</tt> 叙述。如果外层的exception处理机制不存在的话,这就是一个没有被处理的exception( <i>unhandled exception</i> ),然后整个程式会中断,并出现上面出现的错误程式。 <p> </p> </li> </ul> <p> 一个 <tt class="keyword">try</tt> 叙述可以包含许多的except 部分来处理各种不同的exception,但是最多只有一个handler(译:exception之后的叙述)会真正被执行。Handlers只处理在所对应的 <tt class="keyword">try</tt> 部分发生的exception,其他的 try 部分发生的exception则不在处理范围。一个except子句可以处理一个以上的exception,只要用list括弧把它们括起来。例如: </p> <p> </p> <dl> <dd><pre class="verbatim">... except (RuntimeError, TypeError, NameError):<br>... pass<br></pre> </dd> </dl> <p> 最后的一个 except 可以不写出exception 类型的名称,这就当作是一个外卡(wildcard,译:处理所有的exception)来使用。当使用时要特别的小心,因为如果你很有可能就把一个应该被注意的程式错误给隐藏起来了。你也可以在这个except子句里面印出一个错误信息,然后把这个exception再丢(raise)出去(让呼叫你程式的人来处理这个exception)。 </p> <p> </p> <dl> <dd><pre class="verbatim">import string, sys<br><br>try:<br> f = open('myfile.txt')<br> s = f.readline()<br> i = int(string.strip(s))<br>except IOError, (errno, strerror):<br> print "I/O error(%s): %s" % (errno, strerror)<br>except ValueError:<br> print "Could not convert data to an integer."<br>except:<br> print "Unexpected error:", sys.exc_info()[0]<br> raise<br></pre> </dd> </dl> <p> 这个 <tt class="keyword">try</tt> ... <tt class="keyword">except</tt> 的叙述有一个可有可无的else子句( <i>else clause</i> )可以使用,当这个子句存在时,必须是放在所有的except clauses的后面。这个子句里的叙述是当try子句没有发生任何exception时,一定要执行的叙述。请看例子: </p> <p> </p> <dl> <dd><pre class="verbatim">for arg in sys.argv[1:]:<br> try:<br> f = open(arg, 'r')<br> except IOError:<br> print 'cannot open', arg<br> else:<br> print arg, 'has', len(f.readlines()), 'lines'<br> f.close()<br></pre> </dd> </dl> <p> 使用 <tt class="keyword">else</tt> 要比在 <tt class="keyword">try</tt> 子句里面加入多余的程式码来的好,因为这样减少意外的处理到那些不是由 <tt class="keyword">try</tt> ... <tt class="keyword">except</tt> 叙述中保护的程式码所引发的exception。 </p> <p> 当一个exception 发生时,exception本身有一个 连带的值,也叫做这个exception的参数( <i>argument</i> )。至于这个参数是否存在以及其型态,则是由exception的类型所决定。对于有这个参数存在的exception类型来说,你可以在exceptclause的后面加入一个名称(或是list)来接收这个参数的值。请看下例: </p> <p> </p> <dl> <dd><pre class="verbatim">>>> try:<br>... spam()<br>... except NameError, x:<br>... print 'name', x, 'undefined'<br>... <br>name spam undefined<br></pre> </dd> </dl> <p> 如果一个exception 有一个参数的话,当它在没有被处理,当作错误信息印出来的时候,就会成为最后(详细解释(`detail'))的一部份。 </p> <p> Exception的处理者(handlers,exception clause)并不只处理在try clause当中所发生的exception,也会处理所有在tryclause当中所(直接或间接)呼叫的函式所引发的exception。请看下例: </p> <p> </p> <dl> <dd><pre class="verbatim">>>> def this_fails():<br>... x = 1/0<br>... <br>>>> try:<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></pre> </dd> </dl> <p> </p> <h1> <br> 8.4 如何引发例外(Exceptions) </h1> <p> 使用 <tt class="keyword">raise</tt> 叙述可以引发一个特定的 exception,例如: </p> <p> </p> <dl> <dd><pre class="verbatim">>>> raise NameError, 'HiThere'<br>Traceback (innermost last):<br> File "<stdin>", line 1<br>NameError: HiThere<br></pre> </dd> </dl> <p> <tt class="keyword">raise</tt> 的第一个参数是想要引发的exception的类型,第二个参数(可有可无)则是指定这个exception的参数值。 </p> <p> </p> <h1> <br> 8.5 使用者自订的例外(Exceptions) </h1> <p> 程式设计师可以自己命名自己想要的excetion,其方法是指定一个字串给一个变数,或者是自己创造一个新的exception类别来。举例说明: </p> <p> </p> <dl> <dd><pre class="verbatim">>>> class MyError:<br>... def __init__(self, value):<br>... self.value = value<br>... def __str__(self):<br>... return `self.value`<br>... <br>>>> try:<br>... raise MyError(2*2)<br>... except MyError, e:<br>... print 'My exception occurred, value:', e.value<br>... <br>My exception occurred, value: 4<br>>>> raise MyError, 1<br>Traceback (innermost last):<br> File "<stdin>", line 1<br>__main__.MyError: 1<br></pre> </dd> </dl> <p> 许多标准的module都自己自订其exception来报回(report)在他们自己所定义的函式里面所发生的错误。 </p> <p> 有关于classes 更多的讨论请看<a href="node11.html#classes">第九章</a>``类别''。 </p> <p> </p> <h1> <br> 8.6 定义善后的动作 </h1> <p> 在 <tt class="keyword">try</tt> 叙述的机制里面有一个可有可无的子句(optionalclause),其功用是在定义不管什么情况发生下,你都得要做的清除善后的工作。 举例来说: </p> <p> </p> <dl> <dd><pre class="verbatim">>>> try:<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></pre> </dd> </dl> <p> 这个 <i>finally clause</i> 不管你的程式在try里面是否有任何的exception发生都会被执行。当exception发生时,程式会执行finallyclause之后再引发这个exception。当程式的 <tt class="keyword">try</tt> try部分因为 <tt class="keyword">break</tt> 或 <tt class="keyword">return</tt> 而离开时,finally clause也一样会在离开的时候(``onthe way out'')被执行。 </p> <p> 一个 <tt class="keyword">try</tt> 叙述机制应该要有一个或多个exceptclauses,或者是有一个 finally clause,但是不能两个都有。 </p> <p> </p> <div class="navigation"> <table align="Center" width="100%" cellpadding="0" cellspacing="2"> <tbody> <tr> <td><a href="node9.html"><img src="../icons/previous.gif" border="0" height="32" alt="Previous Page" width="32"></a></td> <td><a href="tut.html"><img src="../icons/up.gif" border="0" height="32" alt="Up One Level" width="32"></a></td> <td><a href="node11.html"><img src="../icons/next.gif" border="0" height="32" alt="Next Page" width="32"></a></td> <td align="Center" width="100%">Python 教学文件</td> <td><a href="node2.html"><img src="../icons/contents.gif" border="0" height="32" alt="Contents" width="32"></a></td> <td><img src="../icons/blank.gif" border="0" height="32" alt="" width="32"></td> <td><img src="../icons/blank.gif" border="0" height="32" alt="" width="32"></td> </tr> </tbody> </table> <b class="navlabel">Previous:</b> <a class="sectref" href="node9.html">7.输入(Input)与输出(Output)</a> <b class="navlabel">Up:</b> <a class="sectref" href="tut.html">Python 教学文件</a> <b class="navlabel">Next:</b> <a class="sectref" href="node11.html">9. 类别(Classes)</a> <br> <hr></div> <!--End of Navigation Panel--> <address> </address> <hr>请看<i><a href="about.html">关于此文件…</a></i> 里面有关如何给我们建议的说明。 </body> </html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -