Python 错误检查标准实践
我有一个关于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 个回答
下面的内容是基于~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: 没有这样的文件或目录
绝对不要使用断言。断言应该只在代码有问题时才会失败。外部条件(比如缺少文件)不应该用断言来检查。
正如其他人提到的,断言是可以关闭的。
断言的正式含义是:
条件可能会被评估,也可能不会(所以不要依赖表达式的副作用)。
如果条件为真,程序会继续执行。
如果条件为假,接下来会发生什么是没有定义的。
如果你只是想抛出一个异常,可以使用选项 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
无论如何,先检查文件是否存在(选项 i
或 ii
)都是不推荐的,因为在你检查文件和 Python 尝试打开文件之间的这段时间,文件可能会被删除或者被修改(比如通过符号链接),这可能会导致程序出错或者出现安全隐患。
另外,从 Python 2.6 开始,打开文件的最佳做法是使用 with open(...)
这种写法。这样可以确保即使在 with
块内部发生异常,文件也会被正确关闭。
在 Python 2.5 中,如果你在脚本开头加上
from __future__ import with_statement