我应该为不存在的文件参数引发 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 只是两个相互竞争的思想流派,也不是反模式 ... 虽然总的来说 python 偏爱 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 之前下降
weights = 'noisy-student' ValueError: `weights` 参数应该是 `None`、`imagenet` 或要加载的权重文件的路径
为啥将数组拆箱为不正确的类型不会在 C# 中引发异常? [复制]
skopt 的 gp_minimize() 函数引发 ValueError: array must not contain infs or NaNs