【问题标题】:Python Error-Checking Standard PracticePython 错误检查标准实践
【发布时间】:2010-05-16 12:25:01
【问题描述】:

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

使用断言似乎是检查前置/后置条件的“标准”方式,所以我很想使用这些。但是,当在执行期间使用 -o 标志时,这些断言可能会被关闭,这意味着此检查可能会被关闭并且看起来很冒险。

iii) 根本不处理前置条件

这是因为如果文件路径不存在,无论如何都会产生异常,并且异常消息足够详细,让用户知道文件不存在


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

【问题讨论】:

    标签: python error-handling assert


    【解决方案1】:

    如果您只想引发异常,请使用选项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-block 内发生异常。

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

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

    【讨论】:

      【解决方案2】:

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

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

      assert的形式语义是:

      1. 可能会或可能不会评估条件(因此不要依赖表达式的副作用)。

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

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

      More on this idea.

      【讨论】:

        【解决方案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: No such file or directory

        【讨论】:

          【解决方案4】:

          我认为你应该混合使用 iii) 和 i)。如果你知道一个事实,python 会抛出异常(即 case iii),然后让 python 去做。如果还有其他一些先决条件(例如,您的业务逻辑要求),您应该抛出自己的异常,甚至可能源自 Exception

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2010-10-15
            • 1970-01-01
            • 2016-03-10
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多