我应该为不存在的文件参数引发 ValueError 或 OSError 吗?

Posted

技术标签:

【中文标题】我应该为不存在的文件参数引发 ValueError 或 OSError 吗?【英文标题】:Should I raise ValueError or OSError for non-existent file arguments? 【发布时间】:2015-07-09 08:46:58 【问题描述】:

当程序接收到不存在或不是目录的文件名参数时,我想引发错误。但是什么错误被认为是最佳实践?

我知道ValueError 经常被用来表示无效的参数(我见过several questions 关于它)。我也明白,尤其是在 Python 3.3 (PEP 3151) 中对异常进行重组之后,OSError 是与系统交互相关问题的包罗万象的类别。

所以,我有一个需要文件名参数的程序。如果调用者提供的名称不存在,或者存在但是是一个目录,我应该提出什么错误?这是一个不正确的论点,所以似乎ValueError 适用;但如果我尝试将其作为文件读取,我会得到一个OSError-- 所以不应该返回这个以保持一致性吗?

【问题讨论】:

此时您需要提出任何事情吗?如果文件是否存在确实很重要,那么无论如何可能会出现另一个异常。换句话说:你筹集资金的用例是什么? 如果异常不是为了被捕获,那只是审美问题;但我遵循这背后的原则,所以让我们假设这是一个长时间运行的程序,错误会被捕获,模块会被新参数调用(例如,交互地)。 这在 Python 中有点反模式:你应该请求宽恕,而不是许可。所以,如果你不打算对错误做任何事情,就忽略它,让任何会崩溃的东西崩溃,然后让产生的异常冒泡给调用者。如果您正在编写库,我会在此规则中添加一个异常(没有双关语),在这种情况下,您可能需要自己的异常层次结构,以便用户可以捕获来自您的库的错误(例如 requests 有 @ 987654329@). EAFP ... LBYL 只是两个相互竞争的思想流派,也不是反模式 ... 虽然总的来说 p​​ython 偏爱 EAFP 【参考方案1】:

真的重要吗?(我假设你没有发现这个异常,它纯粹是为了个人查看终端输出的信息目的)操作系统不会看到这些,因此我只会

raise Exception("Invalid Arguments, expected a file that exists not %r"%(filename))

或者当它尝试自然打开文件时让它失败

【讨论】:

如果我让它尝试自然地打开文件,我得到一个OSError...因此这个问题。我更喜欢先看后跳的方法,但我觉得例外不应该取决于我的编码风格。 所以你问你是否应该抓住它并引发不同的操作系统错误?或者如果你应该做 if not os.exists(fname): raise OSError("File Doesnt exist") 这几乎与 fh = open(some_file) 相同,除非你不会得到一个文件句柄,如果它确实存在 好吧,如果我提出 OSError 的结果是相似的,但使用 ValueError 则不是。正如我所写,这就是考虑 OSError 的动机。 在这两种情况下,程序都以非零退出代码退出......操作系统不知道任何这些错误类型......你要做的就是向用户表达什么问题是......你唯一需要担心的是如果你打算捕获错误,以便根据错误类型区分不同的逻辑 好吧,如果你要抓住它,我会引发 OSError 甚至是自定义 FileNotFound 异常......但如果是这样的话,你为什么不让正常的 OSError 冒泡并在级别被抓住你的第二个错误会被抓住......我发誓我不是一个聪明的驴子(或故意困难),这些是你应该考虑的事情

以上是关于我应该为不存在的文件参数引发 ValueError 或 OSError 吗?的主要内容,如果未能解决你的问题,请参考以下文章

重采样引发 ValueError:值在第一个 bin 之前下降

理解 ValueError:python 中的“无效数字”

weights = 'noisy-student' ValueError: `weights` 参数应该是 `None`、`imagenet` 或要加载的权重文件的路径

为啥将数组拆箱为不正确的类型不会在 C# 中引发异常? [复制]

skopt 的 gp_minimize() 函数引发 ValueError: array must not contain infs or NaNs

(Python) 未显示多个引发的 ValueErrors