如何正确引发FileNotFoundError?

zez*_*llo 41 python file-not-found python-3.x

我使用的第三方库很好但不按我想要的方式处理不存在的文件.给它一个不存在的文件,而不是提高旧的

FileNotFoundError: [Errno 2] No such file or directory: 'nothing.txt'
Run Code Online (Sandbox Code Playgroud)

它提出了一些模糊的信息:

OSError: Syntax error in file None (line 1)
Run Code Online (Sandbox Code Playgroud)

我不想处理丢失的文件,不想捕获或处理异常,不想引发自定义异常,既不想要我open文件,也不想创建它,如果它不存在.

我只想检查它是否存在(os.path.isfile(filename)将做的技巧)如果没有,那么只需要引发一个正确的FileNotFoundError.

我试过这个:

#!/usr/bin/env python3

import os

if not os.path.isfile("nothing.txt"):
    raise FileNotFoundError
Run Code Online (Sandbox Code Playgroud)

什么只输出:

Traceback (most recent call last):
  File "./test_script.py", line 6, in <module>
    raise FileNotFoundError
FileNotFoundError
Run Code Online (Sandbox Code Playgroud)

这比"文件无语法中的语法错误"更好,但是如何用正确的消息引发"真正的"python异常,而不必重新实现它?

Mar*_*ers 71

传递参数:

import errno
import os

raise FileNotFoundError(
    errno.ENOENT, os.strerror(errno.ENOENT), filename)
Run Code Online (Sandbox Code Playgroud)

FileNotFoundError是一个子类OSError,它带有几个参数.第一个是来自errno模块的错误代码(总是找不到文件errno.ENOENT),第二个是错误消息(用于os.strerror()获取此错误),并将文件名作为第3个传递.

回溯中使用的最终字符串表示形式是根据这些参数构建的:

>>> print(FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT), 'foobar'))
[Errno 2] No such file or directory: 'foobar'
Run Code Online (Sandbox Code Playgroud)

  • 在 Python 2 中,未定义 `FileNotFoundError`,因此您应该引发 `IOError`/`OSError`,或者将其定义为这些的子类(参见 [this question](/sf/ask/1872169841/ 4614641))。 (4认同)
  • 我觉得有点奇怪的是,当“FileNotFoundError”被记录为与“ENOENT”相对应时,您需要将错误号作为参数传递。(类似的论点适用于“OSError”的其他子类。)也许这应该是一个单独的问题,但是:为什么会这样? (3认同)
  • @chepner:`OSError()`类执行该映射; `OSError(errno.ENOENT,os.strerror(errno.ENOENT),filename)`返回一个`FileNotFound()`实例.但是要创建这样的实例,您仍然需要传递相同的参数.如果变量`e`中的`errno`常量,请坚持`OSError(e,os.strerror(e),path)`.子类都提供与基类相同的接口. (3认同)
  • 完美的!我一直在努力寻找正确的写作方式。 (2认同)
  • 阅读 [`FileNotFoundError` 的文档](https://docs.python.org/3/library/exceptions.html#FileNotFoundError) ("FileNotFoundError [...] Corresponds to errno ENOENT") 引导我明白这一点: FileNotFoundError 构造的第一个和第二个参数对类名来说不是多余的吗?(无论如何,答案似乎是准确的,因为 `print(FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT), 'foobar'))` 和 `print(FileNotFoundError('foobar')` 之间存在差异。 ) (2认同)

Sep*_*rvi 6

在Python中,变量可以引用类型(类),或对象(类的实例):

>>> x = FileNotFoundError
>>> print(type(x))
<class 'type'>

>>> x = FileNotFoundError()
>>> print(type(x))
<class 'FileNotFoundError'>
Run Code Online (Sandbox Code Playgroud)

虽然也可以抛出type FileNotFoundError,但您实际上总是希望抛出从该类构造的对象。构造函数接受与OSError相同的参数。您可以传递标准 POSIX 和 Windows 错误代码,但传递错误消息就足够了。(在您的情况下,标准错误消息“没有这样的文件或目录”并不完全准确,因为如果找到目录,您也会抛出错误。)

if not os.path.isfile("nothing.txt"):
    raise FileNotFoundError("nothing.txt was not found or is a directory")
Run Code Online (Sandbox Code Playgroud)