在 Python 中重新引发异常

问题描述

在 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 语句究竟有效吗?

另外,作者说第一个函数ValueErrorTypeError的情况下输出错误代码-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

无需将异常绑定到显式名称。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...