问题描述
在 Robert Smallshire 和 Austin Bingham 写的非常棒的一本非常棒的书中,有以下代码:
def convert(s):
"""Convert a string to an integer."""
try:
return int(s)
except (ValueError,TypeError) as e:
print("Conversion error: {}".format(str(e)),file=sys.stderr)
raise
之后,作者加入了如下string_log函数
def string_log(s):
v = convert(s)
return log(v)
string_log('ouch')
的输出如下
我无法理解 raise 语句究竟有效吗?
另外,作者说第一个函数在ValueError
和TypeError
的情况下输出负错误代码-1的代码,即第一个函数如下
import sys
def convert(s):
"""Convert a string to an integer."""
try:
return int(s)
except (ValueError,file=sys.stderr)
return -1
然后如果我们运行以下(没有做任何更改string_log()
)是
string_log('cat')
不是pythonic,但为什么呢?
解决方法
如果 convert
在出错时返回 -1
,那么您必须明确检查它以避免 string_log
也返回 -1
。就像 string_log
期望 convert
返回有效字符串一样,调用者也可能如此。让 -1
传播可能会在很长一段时间内不被发现,一旦发生错误确实,就不清楚错误的来源是什么。
如果有异常,string_log
没有捕获异常就不会返回;异常继续向上调用堆栈,直到它被捕获,或者解释器以回溯退出。该回溯将准确地显示异常的来源。
raise
不带参数只会引发最近的异常,而无需编写类似
except (ValueError,TypeError) as e:
print("Conversion error: {}".format(str(e)),file=sys.stderr)
raise e
在这里,您无论如何都在对 e
的调用中使用了 print
,但如果没有,您可以编写
except (ValueError,TypeError):
print("Something bad happened!")
raise
无需将异常绑定到显式名称。