<h3>处理错误</h3>
<p>这是个坏习惯吗?依我看:不,不是。一般来说,这是一种良好的做法:</p>
<pre class="lang-py prettyprint-override"><code>def foo(a, b):
return a / b
def bar(a):
return foo(a, 0)
try:
bar(6)
except ZeroDivisionError:
print("Error!")
</code></pre>
<p>原因很简单:处理错误的代码集中在主程序中的一个点上</p>
<p>在某些编程语言中,可能引发的异常必须在函数/方法级别声明。Python则不同:它是一种脚本语言,缺少这样的特性。当然,因此,有时您可能会意外地遇到异常,因为您可能不知道正在调用的其他代码可能会引发这样的异常。但这没什么大不了的:要解决这种情况,您的主程序中有<code>try...except...</code></p>
<p>您可以通过以下方式弥补对可能异常的了解不足:</p>
<ul>
<li>记录可能提出的例外情况;如果编程语言本身没有帮助,您需要通过提供更广泛的文档来弥补这一缺陷</李>
<li>进行广泛的测试</李>
</ul>
<p>一般来说,遵循您的选项b)毫无意义。事情可能更加明确,但代码本身并不是这个明确信息的正确位置。相反,这些信息应该是函数/方法文档的一部分</p>
<p>因此,不是</p>
<pre class="lang-py prettyprint-override"><code>def bar(a):
try:
ret = foo(a, 0)
except ZeroDivisionError:
raise
return ret
</code></pre>
<p>。。。写:</p>
<pre class="lang-py prettyprint-override"><code>def bar(a):
"""
Might raise ZeroDivisionError
"""
return foo(a, 0)
</code></pre>
<p>或者像我写的那样:</p>
<pre class="lang-py prettyprint-override"><code>#
# @throws ZeroDivisionError Does not work with zeros.
#
def bar(a):
return foo(a, 0)
</code></pre>
<p>(但您在文档中究竟依赖哪种语法是完全不同的问题,超出了本问题的范围。)</p>
<p>在某些情况下,捕获函数/方法中的异常<em>是一种很好的做法。例如,如果您<em>希望</em>一个方法以任何方式成功,即使某些内部操作可能失败,也会出现这种情况。(例如,如果您试图读取一个文件,但如果该文件不存在,您希望使用默认数据。)但仅仅为了再次引发异常而捕获异常通常没有任何意义:目前我甚至无法想出这样做可能有用的情况(尽管可能有一些特殊情况)。如果您希望提供可能引发此类异常的信息,请不要依赖用户查看实现,而是查看函数/方法的文档</p>
<h3>输出错误</h3>
<p>无论如何,我不会按照您的方法只打印一条简单的错误消息:</p>
<pre class="lang-py prettyprint-override"><code>try:
bar(6)
except ZeroDivisionError:
print("Error!")
</code></pre>
<p>提出合理的、人类可读的、简单的错误消息是相当费力的。我曾经这样做过,但是这种方法需要的代码量是巨大的。根据我的经验,最好是失败并打印出堆栈跟踪。使用此堆栈跟踪,通常任何人都可以很容易地找到错误的原因</p>
<p>不幸的是,Python在错误输出中没有提供非常可读的堆栈跟踪。为了弥补这一点,我实现了自己的错误输出处理(可重用为模块),甚至使用了颜色,但这是另一回事,可能也有点超出了这个问题的范围</p>