Python文档提供的例外指南

时间:2012-10-25 17:19:38

标签: python exception

根据关于习语和反成语的in relation to exceptions的Python文档:“你应该尝试尽可能少地使用你的代码中的除了子句 - 你使用的那些通常会在内部调用成功,或者是主要功能的全能。“分段考虑这句话......

  

“你应该尝试尽可能少地使用代码中的子句”

像我这样的新手有点困惑,我认为在Python中使用EAFP样式-i.e是一种很好的做法。许多tryexcept语句。或者我错过了这一点?

  

“你使用的那些通常是在应该总是成功的电话里面”

我不明白这里的意思。

  

“或主要功能中的全能。”

因此,对于任何抛出异常的代码来说,它只是简单地将它传递给调用堆栈,直到它达到你真正通用的异常处理的最高级别时才是好的风格?

4 个答案:

答案 0 :(得分:2)

  

“你应该尝试尽可能少地使用代码中的子句”

除了例外情况,您的代码很容易丢失:

def solve_linear(mat1, mat2):
    det1 = determinant(mat1)
    det2 = determinant(mat2)
    try:
        return det1 / det2
    except ZeroDivisionError:
        raise NoSolution

在这里,让ZeroDivisionError传播可能很好。你不需要抓住它。

  

“你使用的那些通常是在应该总是成功的电话里面”

例如,查看此代码读取文件或返回缓存值。尽管有KeyError例外,它通常会成功:

def read_file(path):
    try:
        return cache[path]
    except KeyError:
        fp = open(path, 'rb')
        data = fp.read()
        fp.close()
        cache[path] = data
        return data
  

“或主要功能中的全能。”

如果您的程序是交互式的,那么您可能希望捕获顶级的几乎所有内容。这是交互式命令行程序的顶部循环:

def main():
    while True:
        try:
            text = raw_input('enter command: ')
            cmd = parse_command(text)
        except EOFError:
            return
        except KeyboardInterrupt:
            return
        except ValueError:
            print 'Syntax error'
            continue

        try:
            run_cmd(cmd)
        except SystemExit:
            raise
        except Exception:
            traceback.print_exc()

答案 1 :(得分:1)

我认为关键是异常应仅用于“特殊”情况。这就是“在通常会成功的通话中”使用背后的意义。这种情况的一个例子可能是一些计算,在一些非常奇怪的情况下,必须进行除零。然后你可以将它包含在try / except语句中以处理这种可能性。

主要功能中的catch-all适用于同一场景。假设您的计算最终在调用堆栈深处的某处除以零。从这一点开始,你无法继续,因此在失败时正确地使用try / except语句是没有意义的。如果只有一个可以从错误中合理恢复的更高级别更有意义。

他们在文档中给出的示例就是一个例子。当调用'get_status'时,你会希望文件存在。如果没有,那么你有except语句来处理(尽管如上所述,在那种特殊情况下'with'语句要好得多。)

答案 2 :(得分:1)

关于第一点,使用异常的整点是你不必将每一行包装在一起!例如。在C中,错误通常由函数调用的返回值确定。因此,如果要捕获所有错误,则必须在每次调用后检查这些错误。使用Python,您可以将一个(可能很大的)语句块组合在一个try / except块中,并且只处理所有错误一次

第二点是(如果可能的话)你想要解决接近它们发生点的故障。例如。您正在从网络读取数据并获得零字节。在这种情况下,等待再试一次通常是完全可以的。

最后一点是,有时错误是如此之大以至于无法在低级别处理。例如。如果你试图打开一个不存在的文件,它将失败。并且您的程序无法执行与文件内容有关的任何操作。最好在程序的顶层处理它,并询问用户另一个文件名或退出程序。

答案 3 :(得分:1)

Python哲学通常是“请求宽恕,而不是许可”。但我们的想法是不使用try-except子句来捕获所有可能的错误。理想情况下,每个try-except只会捕获相关的错误。

BAD(未指定特定的例外类型):

a = [1, 2, 3]
i = 3
try:
    print a[i]
except:
    print "Not found!"

GOOD(仅处理我们期望获得的异常):

a = [1, 2, 3]
i = 3
try:
    print a[i]
except IndexError:
    print "Not found!"

这一点很重要的原因是我们不会掩盖其他可能的代码错误。如果在此示例中i为1.8,该怎么办?第一个示例将打印Not Found!,模糊真实问题,但第二个示例将返回TypeError: list indices must be integers, not float,让我们知道代码中存在逻辑缺陷。