open()函数出现FileNotFoundError/IOError错误:'[Errno 2] No such file or directory'。

127

我正在尝试从我的Python脚本中打开文件recentlyUpdated.yaml。但是当我尝试使用以下代码时:

open('recentlyUpdated.yaml')

我收到一个错误,内容为:

IOError: [Errno 2] No such file or directory: 'recentlyUpdated.yaml'

为什么?我该如何解决这个问题?


1
确保您可以在文件资源管理器中看到所有文件扩展名...就像我吃了亏一样。 - Xetrov
1
使用PyCharm?将.csv文件所在的文件夹标记为“源根目录” ->右键单击文件夹并选择“标记目录为”,然后选择“源根目录”。此外,在运行/调试配置中检查工作目录 ->运行菜单->编辑配置->在左窗格中选择Python文件 ->确保工作目录是项目的根目录。 https://www.jetbrains.com/help/pycharm/creating-and-editing-run-debug-configurations.html - Hassan Naqvi
对我来说,问题在于我的文件是符号链接。将文件夹复制到另一台计算机上后,底层数据丢失了,因为该计算机上不存在这些数据。这让我明白了要始终在终端中检查发生了什么。 - scottlittle
3
请参考什么是当前工作目录? - tripleee
11个回答

159
  • 确保文件存在(并且有正确的文件扩展名):使用os.listdir()查看当前工作目录中的文件列表。
  • 使用os.getcwd()确保你在预期的目录中。
    (如果你从IDE启动代码,可能会在不同的目录中。)
  • 然后可以选择:
    • 调用os.chdir(dir),其中dir是包含该文件的目录。然后,只使用文件名打开文件,例如:open("file.txt")
    • open调用中指定文件的绝对路径。
  • 如果您的路径使用反斜杠,请使用原始字符串(r""),例如:dir = r'C:\Python32'
    • 如果您不使用原始字符串,则必须转义每个反斜杠:'C:\\User\\Bob\\...'
    • 在Windows上,斜杠也可以使用 'C:/Python32' 并且不需要转义。

让我澄清一下Python如何查找文件:

  • 绝对路径是以计算机根目录开头的路径,例如Windows上的C:\Python\scripts
  • 相对路径是不以计算机根目录开头的路径,而是相对于称为工作目录的东西。可以通过调用os.getcwd()查看Python的当前工作目录。

如果您尝试执行open('sortedLists.yaml'),Python将看到您正在传递相对路径,因此它将在当前工作目录中搜索该文件。

调用os.chdir()将更改当前工作目录。

示例:假设file.txt位于C:\Folder中。

打开它,可以这样做:

os.chdir(r'C:\Folder')
open('file.txt') # relative path, looks inside the current working directory
open(r'C:\Folder\file.txt') # absolute path

3
在Linux上,像~/这样的主目录路径也不起作用。因此,您需要使用/home/user/temp/file.txt而不是~/temp/file.txt - Radek Daniluk
@Radek 是的,~是一个shell中的快捷方式,而不是文件系统中的。如果你想让Python来扩展它,可以使用os.path.expanduser()或者pathlib.Path.expanduser() - wjandrea
非常感谢,os.getcwd() 给了我很大的线索,让我知道自己在哪里。 - smoothumut
os.chdir改变了程序的全局状态,可能会在脚本的其他部分引入错误。我不建议使用这个。 - Matthias

36
很可能的问题是,你使用了相对文件路径打开文件,但当前工作目录并不是你认为的那样。这是一个常见误解,认为相对路径是相对于Python脚本的位置,但事实并非如此。相对文件路径始终相对于当前工作目录,而当前工作目录不一定是Python脚本的位置。你有三个选择:
  • Use an absolute path to open the file:

    file = open(r'C:\path\to\your\file.yaml')
    
  • Generate the path to the file relative to your python script:

    from pathlib import Path
    
    script_location = Path(__file__).absolute().parent
    file_location = script_location / 'file.yaml'
    file = file_location.open()
    

    (See also: How do I get the path and name of the file that is currently executing?)

  • Change the current working directory before opening the file:

    import os
    
    os.chdir(r'C:\path\to\your\file')
    file = open('file.yaml')
    

其他可能导致“文件未找到”错误的常见错误包括:

  • Accidentally using escape sequences in a file path:

    path = 'C:\Users\newton\file.yaml'
    # Incorrect! The '\n' in 'Users\newton' is a line break character!
    

    To avoid making this mistake, remember to use raw string literals for file paths:

    path = r'C:\Users\newton\file.yaml'
    # Correct!
    

    (See also: Windows path in Python)

  • Forgetting that Windows doesn't display file extensions:

    Since Windows doesn't display known file extensions, sometimes when you think your file is named file.yaml, it's actually named file.yaml.yaml. Double-check your file's extension.


7

文件可能已经存在,但其路径可能不同。尝试编写文件的绝对路径。

尝试使用os.listdir()函数检查Python是否至少看到该文件。

像这样尝试:

file1 = open(r'Drive:\Dir\recentlyUpdated.yaml')

1
它似乎无法识别我的电脑上的任何文件路径。有没有办法搜索文件?@sshekar - Santiago

3

理解绝对路径和相对路径

术语路径的意思就是字面上的意思。它展示了进入和离开文件夹以找到文件所需的步骤。路径上的每一步都可以是文件夹名称、特殊名称.(表示当前文件夹)或特殊名称..(表示返回/进入父文件夹)。

术语绝对路径相对路径在这里也有它们通常的英文含义。相对路径显示某个起始点相对于某个位置的位置;绝对路径是从顶部开始的位置。

以路径分隔符开头,或者在Windows上以驱动器号后跟路径分隔符(例如C:/foo)的路径是绝对路径。(在Windows上还有UNC路径,它们必然是绝对路径。大多数人永远不必担心这些。)

直接以文件或文件夹名称开头的路径,或者以驱动器号后跟文件或文件夹名称(例如C:foo)的路径,在Windows上是相对路径。
理解“当前工作目录”
相对路径是“相对于”所谓的当前工作目录(以下简称CWD)。在命令行中,Linux和Mac在所有驱动器上使用一个共同的CWD。(整个文件系统有一个共同的“根”,可能包含多个物理存储设备。)Windows有些不同:它记住了每个驱动器的最近CWD,并具有单独的功能来在驱动器之间切换,恢复那些旧的CWD值。
每个进程(包括终端/命令窗口)都有自己的CWD。当从命令行启动程序时,它将获取终端/命令进程正在使用的CWD。当从GUI中启动程序(通过双击脚本,将某物拖放到脚本上,或将脚本拖放到Python可执行文件上)或使用IDE启动程序时,CWD可能是根据详细信息而变化的任何数量的东西。
重要的是,CWD不一定是脚本所在的位置。
脚本的当前工作目录可以使用os.getcwd来检查,也可以使用os.chdir来修改。每个集成开发环境都有自己的规则来控制初始的工作目录,请查阅文档以了解详情。
要将当前工作目录设置为包含当前脚本的文件夹,请确定该路径,然后进行设置。
os.chdir(os.path.dirname(os.path.abspath(__file__)))

验证实际文件名和路径
  • 有很多原因导致文件路径与预期不符。例如,有时人们在Windows上期望 C:/foo.txt 意味着“桌面上名为 foo.txt 的文件”。这是错误的。该文件实际上通常位于 C:/Users/name/Desktop/foo.txt(将 name 替换为当前用户的用户名)。如果Windows配置为将其放在其他位置,则可能会放在其他位置。要以便携方式找到桌面的路径,请参见 如何获取桌面位置?

    在相对路径中错误地计算 ..,或在路径中重复一个文件夹名称也很常见。在编程构建路径时要特别小心。最后,要记住,当已经在根目录中时,.. 是没有任何效果的(在Linux或Mac上为 /,在Windows上为驱动器根目录)。

    在基于用户输入构建路径时要格外小心。如果输入未经过清理处理,可能会发生糟糕的事情(例如,允许用户解压缩文件到某个文件夹,从而覆盖一些重要内容,或者不应允许用户写入文件的文件夹)。

  • 另一个常见的问题是,在Python程序中指定的绝对路径中,表示当前用户主目录的特殊快捷方式 ~ 无法使用。该路径的部分必须明确转换为实际路径,使用 os.path.expanduser。请参见 为什么我被迫在Python中使用 os.path.expanduser?os.makedirs在我的路径中不理解“~”

  • 请记住,os.listdir 只会返回文件名,不包括路径。如果尝试迭代以这种方式列出的目录,只有该目录是当前工作目录才能正常工作。

  • 确保实际文件名也很重要。Windows 在图形界面中隐藏文件名扩展名的选项。如果你在窗口中看到 foo.txt,则该文件的实际名称可能是 foo.txt.txt 或其他内容。可以在设置中禁用此选项。还可以使用命令行验证文件名;dir 命令将告诉您文件夹中的真相(当然,Linux/Mac 的等效命令是 ls;但首先不应该出现这个问题)。

  • 普通字符串中的反斜杠是转义序列。这导致在 Windows 上尝试使用反斜杠作为路径分隔符时出现问题。然而,使用反斜杠并非必要,通常也不可取。请参见 如何在Python字符串字面量中编写Windows路径?

  • 当尝试使用类似 w 的文件模式创建新文件时,仍然需要存在新文件的路径,即所有中间文件夹。例如,请参阅 如果目录不存在,则尝试使用 open(filename, 'w' ) 会导致 IOError: [Errno 2] No such file or directory。还要记住,新文件名必须有效。特别是,将日期以 MM/DD/YYYY 格式插入到文件名中是行不通的,因为斜杠 / 将被视为路径分隔符


3
也许您关闭了“file1”。
只需使用“w”标记创建新文件即可:
file1 = open('recentlyUpdated.yaml', 'w')

mode是一个可选的字符串,用于指定文件打开的模式。默认值为'r',表示以文本模式读取文件。其他常见的值包括'w'用于写入(如果文件已经存在,则截断文件)...

(另请参阅https://docs.python.org/3/library/functions.html?highlight=open#open)


2
如果是VSCode,请查看工作区。如果您在其他工作区,则可能会出现此错误。

1
确保文件路径中的所有文件夹都存在。
我之所以遇到这个错误,是因为对我来说不明显的是,文件夹是否被创建了,理论上,代码中调用的函数应该会做到这一点。
import os

file_path = input('Input file path')
dir_path = os.path.dirname(file_path)

os.makedirs(dir_path, exist_ok=True)

with open(file_path) as file:
    file.write("Written!")

在 OP 的情况下,他只是在读取文件,所以它应该存在于他提供的路径中。我们可能经常忘记 open 函数的 w 标志(例如 open('/path/to/file', 'w')),从而导致出现此错误。

0
一个(可能的)失败场景:
- 如果目标文件是一个符号链接,并且你通过 os.scandir()os.listdir() 等方式获取了引用,然后尝试在一个损坏的符号链接上调用 .stat(),那么 stat() 调用将尝试针对不存在的符号链接目标而不是符号链接本身。
默认情况下,使用 .stat(*, follow_symlinks=True) 调用 .stat();使用 .stat(follow_symlinks=False) 来防止跟随(损坏的)符号链接。

0

检查所提到的路径,看它是绝对路径还是相对路径。

如果是这样的-->/folder/subfolder/file-->计算机将在根目录中搜索文件夹。

如果是这样的-->./folder/subfolder/file-->计算机将在当前工作目录中搜索文件夹。


0

如果您正在使用像VScode这样的IDE,请确保您已经从存放要访问的文件的同一目录中打开了IDE。

例如,如果您想访问位于“文档”内的file.txt文件,请尝试通过右键单击该目录并点击“使用...打开”来打开IDE。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接