Python 错误检查标准实践

16 投票
4 回答
17517 浏览
提问于 2025-04-15 22:45

我有一个关于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

使用assert似乎是检查前提/后提条件的“标准”方法,所以我有点想用这个。不过,如果在执行时使用了-o标志,这些assert可能会被关闭,这样一来,这个检查就可能失效,这听起来有点危险。

iii) 完全不处理前提条件

这是因为如果文件路径不存在,反正会产生一个异常,而且异常信息足够详细,用户可以知道文件不存在。


我只是想知道以上哪种方法是我在代码中应该使用的标准做法。

4 个回答

3

下面的内容是基于~unutbu的例子。如果文件不存在,或者出现其他类型的输入输出错误,错误信息中也会包含文件名:

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

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

4

绝对不要使用断言。断言应该只在代码有问题时才会失败。外部条件(比如缺少文件)不应该用断言来检查。

正如其他人提到的,断言是可以关闭的。

断言的正式含义是:

  1. 条件可能会被评估,也可能不会(所以不要依赖表达式的副作用)。

  2. 如果条件为真,程序会继续执行。

  3. 如果条件为假,接下来会发生什么是没有定义的。

关于这个概念的更多信息

16

如果你只是想抛出一个异常,可以使用选项 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 中,如果你在脚本开头加上

from __future__ import with_statement

撰写回答