我对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不存在,那么无论如何都会产生异常,并且异常消息足够详细,用户可以知道该文件不存在
我只是想知道上面哪一项是我应该用于我的代码的标准做法。
答案 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
在任何情况下都不首先检查文件是否存在(选项i
或ii
)因为在检查或断言发生之间以及python尝试打开文件之间的时间内,有可能删除或更改文件(例如使用符号链接),这可能导致错误或安全漏洞。
此外,从Python 2.6开始,打开文件时的最佳做法是使用with open(...)
语法。这可以保证文件将被关闭,即使with
- 块内发生异常。
在Python 2.5中,如果您在脚本前加上
,则可以使用with
语法
from __future__ import with_statement
答案 1 :(得分:4)
绝对不要使用断言。断言只有在代码错误时才会失败。不应使用断言检查外部条件(例如丢失的文件)。
正如其他人所指出的那样,可以关闭断言。
断言的形式语义是:
可能会或可能不会评估这种情况(所以不要依赖表达的副作用)。
如果条件为真,则继续执行。
如果条件为假,则未定义会发生什么。
答案 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
。
使用断言太脆弱了,因为它们可能会被关闭。