【发布时间】:2019-09-17 12:55:18
【问题描述】:
有时我有一系列不同的事情可以尝试完成一项任务,例如。 G。如果我需要获取记录,我可以先尝试查找记录,如果失败,我可以创建丢失的记录,如果也失败,我可以使用磁带代替。
通过抛出我的代码需要捕获的异常来表示失败。
在 Python 中,这看起来像这样:
try:
record = find_record()
except NoSuchRecord:
try:
record = create_record()
except CreateFailed:
record = tape
这已经有堆积压痕的缺点。如果我有五个选项,这段代码就不会好看。
但是当try-except 子句也有else 子句时,我发现问题更大:
try:
record = find_record()
except NoSuchRecord:
try:
record = create_record()
except CreateFailed:
record = tape
logger.info("Using a tape now")
else:
logger.info("Created a new record")
else:
logger.info("Record found")
find_record() 和对应的Record found 消息距离尽可能远,这使得代码难以阅读。 (将else 子句的代码直接移动到try 子句中只是一种选择,如果此代码肯定不会引发except 语句中捕获的异常之一,因此这不是通用解决方案。)
再一次,这种丑陋随着嵌套层数的增加而变得更糟。
有没有更好的方法将其放入 Python 代码中
- 不改变行为和
- 同时将一个主题的
try和except子句紧密结合在一起和/或 - 或许还能避免堆积嵌套和缩进?
【问题讨论】:
-
把它分成两个函数?
-
您是否致力于使用异常来表示异常的函数结果?如果
find_record和create_record在失败时返回None而不是引发异常,这可能会为您的代码块打开一些设计可能性。 -
如果有相关的失败情况可以考虑创建一个自定义的ErrorHandler。
-
我不认为有一个普遍的答案。设计将由每个函数返回和/或可以引发的确切内容决定。
-
@chepner 我经常偶然发现这件事,所以我想有一个通用的方法,而不是只在一种情况下有效的专门方法。要捕获的异常可能是
IndexError或ValueError之类的一般细项,因此我想将try子句保持尽可能小,以避免无意中捕获其他内容。