【问题标题】:Python 3: Open file in read mode without raising an exception? [duplicate]Python 3:以读取模式打开文件而不引发异常? [复制]
【发布时间】:2021-09-19 19:29:06
【问题描述】:

我正在尝试编写一段代码,每次运行 Python3 脚本时都会打开一个新文件。

我正在使用递增的数字构造文件名。

例如,以下是一些应生成的有效文件名示例:

output_0.csv
output_1.csv
output_2.csv
output_3.csv

在下一次运行脚本时,下一个要使用的文件名应该是output_4.csv

在 C/C++ 中,我将通过以下方式执行此操作:

  • 进入无限循环
  • 尝试以“读取”模式打开第一个文件名
  • 如果文件已打开,请增加文件名编号并重复
  • 如果文件未打开,则跳出循环并以“写入”模式重新打开文件

这在 Python 3 中似乎不起作用,因为以读取模式打开一个不存在的文件会引发异常。

一种可能的解决方案是将打开的文件代码块移动到 try-catch 块中。但这似乎不是一个特别优雅的解决方案。

这是我迄今为止在代码中尝试过的内容

# open a file to store output data
filename_base = "output"
filename_ext = "csv"
filename_number = 0

while True:
    filename_full = f"{filename_base}_{filename_number}.{filename_ext}"
    with open(filename_full, "r") as f:
        if f.closed:
            print(f"Writing data to {filename_full}")
            break
        else:
            print(f"File {filename_full} exists")
            filename_number += 1

with open(filename_full, "w") as f:
    pass

如上所述,此代码在尝试打开“读取”模式下不存在的文件时会崩溃。

【问题讨论】:

标签: python python-3.x file-io


【解决方案1】:

使用 pathlib,您可以检查 Path.is_file(),它在遇到文件或文件的符号链接时返回 True

from pathlib import Path

filename_base = "output"
filename_ext = "csv"
filename_number = 0

filename_full = f"{filename_base}_{filename_number}.{filename_ext}"
p = Path(filename_full)

while p.is_file() or p.is_dir():
    filename_number += 1
    p = Path(f"{filename_base}_{filename_number}.{filename_ext}")

当文件不存在时,此循环应该退出,以便您可以打开它进行写入。

【讨论】:

  • 一个不错的解决方案。我只看到一个潜在的问题,即目录之类的东西存在的地方,而不是文件。是否有一个版本使用某些东西代替is_file() 来检测任何路径的存在,而不仅仅是文件。 (Simlink、目录等)
  • is_file() 将为符号链接返回 True,我已经稍微更新了答案以考虑目录
【解决方案2】:

您可以在使用之前检查文件是否存在

os.path.exists(filename)

【讨论】:

    【解决方案3】:

    您可以使用操作系统模块检查文件路径是否为文件,然后打开它:

    import os
    
    file_path = './file.csv'
    
    if(os.path.isfile(file_path)):
        with open(file_path, "r") as f:
    

    【讨论】:

      【解决方案4】:

      这应该可行:

      filename_base = "output"
      filename_ext = "csv"
      filename_number = 0
      
      while True:
          filename_full = f"{filename_base}_{filename_number}.{filename_ext}"
          try:
            with open(filename_full, "r") as f:
                print(f"File {filename_full} exists")
                filename_number += 1
          except FileNotFoundError:
            print("Creating new file")
            open(filename_full, 'w');
            break;
      

      【讨论】:

        【解决方案5】:

        您可以os.path.exists 来检查文件是否已经存在,例如

        import os
        print(os.path.exists("output_0.csv"))
        

        或利用你的名字的事实

        output_0.csv
        output_1.csv
        output_2.csv
        output_3.csv
        

        如此规律,像这样利用glob.glob

        import glob
        existing = glob.glob("output_*.csv")
        print(existing)  # list of existing files
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-05-02
          • 1970-01-01
          • 2019-06-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-01-16
          相关资源
          最近更新 更多