我有一个类NameDatabase
,可以打开一个sqlite文件。好几件事
可能会出错,例如格式错误的数据库,错误的架构等。这通常会导致
异常(在我的情况下为sqlite3.Error
)。
我不想让这个异常逃脱我的课程。相反,我想给
调用者我自己的异常类(推理:除了NameDatabase
我也有
用于图像和GPS轨道的课程,我想向呼叫者展示一个共同的
要处理的例外情况清单。)
首先,这是一个好主意吗?第二,我最好怎么做呢?
我目前的代码:
class FileParseError(...): pass
class NameDatabase:
def __init__(self, fname):
self.fname = fname
try:
self.conn = sqlite3.connect(fname)
# Check if we can query the DB and if the schema is ok.
self.conn.execute('SELECT count(*) FROM names')
except sqlite3.Error:
raise FileParseError("Not a valid database: '%s'", fname)
这有效,但提供了双重追溯(在处理上述异常时,发生了另一个异常)。我理想的是原始的追溯,以及我自己的类型FileParseError
的例外(它可以存储关于原始异常的一些信息)。
我知道我可以使用sys.exc_info()
来实现这样的目标
异常处理程序并在外部重新引发异常,但看起来如此
凌乱,因为我必须在except子句中设置一个标志来记住处理
之后出错。还有更好的方法吗?
exc = None
try:
...
except sqlite3.Error:
exc = sys.exc_info()
if exc:
raise FileParseError("Invalid DB '%s': %s", fname, str(exc[1])), None, exc[2]
平台:Windows上的CPython 3.3。
类似的问题:10555671正是我现在拥有的。我正在寻找避免双追溯的东西,同时避免手动exc
标志设置和再检查 - 除了。
答案 0 :(得分:5)
看起来您想要将现有的新异常链接起来。可以使用PEP 3134引入的语法来完成。或者,您可以使用PEP 409中添加的语法完全抑制先前的异常。
要链接异常,请在as
语句中为已捕获的异常提供except
的名称,然后在from
语句末尾使用名称raise
。像这样:
except sqlite3.Error as e:
raise FileParseError("Not a valid database: '%s'", fname) from e
如果要完全禁止sqlite错误,而不是仅将其转换为其他异常类型,则可以在from None
语句中使用raise
:
except sqlite3.Error:
raise FileParseError("Not a valid database: '%s'", fname) from None
当上下文被抑制时,内部异常仍然可用,但它不会在回溯中打印出来。
如果您想更详细地了解异常链接的问题,您应该阅读上面链接的PEP,也可能是PEP 415,它描述了PEP 409的更新实现。