Python 错误检查标准实践

发布于 2024-09-02 02:24:28 字数 760 浏览 4 评论 0原文

我有一个关于 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 os.path.exists(filepath), 'File does not exist: %s' % filepath

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

iii)根本不处理前提条件

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


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

I have a question regarding error checking in Python. Let's say I have a function that takes a file path as an input:

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

One possible precondition would be that the file should exist.

There are a few possible ways to check for this precondition, and I'm just wondering what's the best way to do it.

i) Check with an if-statement:

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

This is the way that I would usually do it, though the same IOException would be raised by Python if the file does not exist, even if I don't raise it.

ii) Use assert to check for the precondition:

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

Using asserts seems to be the "standard" way of checking for pre/postconditions, so I am tempted to use these. However, it is possible that these asserts are turned off when the -o flag is used during execution, which means that this check might potentially be turned off and that seems risky.

iii) Don't handle the precondition at all

This is because if filepath does not exist, there will be an exception generated anyway and the exception message is detailed enough for user to know that the file does not exist


I'm just wondering which of the above is the standard practice that I should use for my codes.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

妖妓 2024-09-09 02:24:28

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

If all you want to do is raise an exception, use option iii:

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

To handle exceptions in a special way, use a try...except block:

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

Under no circumstance is it preferable to check the existence of the file first (option i or ii) because in the time between when the check or assertion occurs and when python tries to open the file, it is possible that the file could be deleted, or altered (such as with a symlink), which can lead to bugs or a security hole.

Also, as of Python 2.6, the best practice when opening files is to use the with open(...) syntax. This guarantees that the file will be closed, even if an exception occurs inside the with-block.

In Python 2.5 you can use the with syntax if you preface your script with

from __future__ import with_statement
画骨成沙 2024-09-09 02:24:28

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

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

断言的正式语义是:

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

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

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

有关此想法的更多信息

Definitely don't use an assert. Asserts should only fail if the code is wrong. External conditions (such as missing files) shouldn't be checked with asserts.

As others have pointed out, asserts can be turned off.

The formal semantics of assert are:

  1. The condition may or may not be evaluated (so don't rely on side effects of the expression).

  2. If the condition is true, execution continues.

  3. It is undefined what happens if the condition is false.

More on this idea.

时光磨忆 2024-09-09 02:24:28

以下内容扩展自 ~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:没有这样的文件或目录

The following extends from ~unutbu's example. If the file doesn't exist, or on any other type of IO error, the filename is also passed along in the error message:

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

滴情不沾 2024-09-09 02:24:28

我认为你应该混合使用 iii) 和 i)。如果你确实知道 python 会抛出异常(即情况 iii),那么就让 python 来做吧。如果还有一些其他先决条件(例如,您的业务逻辑要求),您应该抛出自己的异常,甚至可能从Exception派生。

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

I think you should go with a mix of iii) and i). If you know for a fact, that python will throw the exception (i.e. case iii), then let python do it. If there are some other preconditions (e.g. demanded by your business logic) you should throw own exceptions, maybe even derive from Exception.

Using asserts is too fragile imho, because they might be turned off.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文