Python错误检查标准实践

时间:2010-05-16 12:25:01

标签: python error-handling assert

我对Python中的错误检查有疑问。假设我有一个将文件路径作为输入的函数:

def myFunction(filepath):
    infile = open(filepath)
    #etc etc...

一个可能的先决条件是该文件应该存在。

有几种方法可以检查这个前提条件,我只是想知道最好的方法是什么。

i)用if语句检查:

if not os.path.exists(filepath):
    raise IOException('File does not exist: %s' % filepath)

这是我通常会这样做的方式,尽管如果文件不存在,Python会引发相同的IOException,即使我没有提出它。

ii)使用assert检查前提条件:

assert os.path.exists(filepath), 'File does not exist: %s' % filepath

使用asserts似乎是检查前/后条件的“标准”方式,所以我很想使用它们。但是,在执行期间使用-o标志时,这些断言可能会被关闭,这意味着可能会关闭此检查,这似乎有风险。

iii)不要完全处理前提条件

这是因为如果filepath不存在,那么无论如何都会产生异常,并且异常消息足够详细,用户可以知道该文件不存在


我只是想知道上面哪一项是我应该用于我的代码的标准做法。

4 个答案:

答案 0 :(得分:15)

如果您要做的只是提出异常,请使用选项iii

def myFunction(filepath):
    with open(filepath) as infile:
        pass

要以特殊方式处理异常,请使用try...except块:

def myFunction(filepath):
    try:
        with open(filepath) as infile:
            pass
    except IOError:
        # special handling code here

在任何情况下都不首先检查文件是否存在(选项iii)因为在检查或断言发生之间以及python尝试打开文件之间的时间内,有可能删除或更改文件(例如使用符号链接),这可能导致错误或安全漏洞。

此外,从Python 2.6开始,打开文件时的最佳做法是使用with open(...)语法。这可以保证文件将被关闭,即使with - 块内发生异常。

在Python 2.5中,如果您在脚本前加上

,则可以使用with语法
from __future__ import with_statement

答案 1 :(得分:4)

绝对不要使用断言。断言只有在代码错误时才会失败。不应使用断言检查外部条件(例如丢失的文件)。

正如其他人所指出的那样,可以关闭断言。

断言的形式语义是:

  1. 可能会或可能不会评估这种情况(所以不要依赖表达的副作用)。

  2. 如果条件为真,则继续执行。

  3. 如果条件为假,则未定义会发生什么。

  4. More on this idea

答案 2 :(得分:3)

以下内容来自~unutbu的例子。如果文件不存在,或者出现任何其他类型的IO错误,则文件名也会在错误消息中传递:

path = 'blam'
try:
    with open(path) as f:
        print f.read()
except IOError as exc:
    raise IOError("%s: %s" % (path, exc.strerror))

=> IOError:blam:没有这样的文件或目录

答案 3 :(得分:1)

我认为你应该选择iii)和i)。如果你知道一个事实,那个python将抛出异常(即case iii),那么让python来做。如果存在其他一些前提条件(例如业务逻辑要求),则应该抛出自己的异常,甚至可能来自Exception

使用断言太脆弱了,因为它们可能会被关闭。