Python 3: Open file in read mode without raising an exception?

Viewed 766

I am trying to write a block of code which opens a new file every time a Python3 script is run.

I am constructing the filename using an incrementing number.

For example, the following are some examples of valid filenames which should be produced:

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

On the next run of the script, the next filename to be used should be output_4.csv.

In C/C++ I would do this in the following way:

  • Enter an infinite loop
  • Try to open the first filename, in "read" mode
  • If the file is open, increment the filename number and repeat
  • If the file is not open, break out of the loop and re-open the file in "write" mode

This doesn't seem to work in Python 3, as opening a non-existing file in read mode causes an exception to be raised.

One possible solution might be to move the open file code block inside a try-catch block. But this doesn't seem like a particularly elegant solution.

Here is what I tried so far in code

# 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

As explained above this code crashes when trying to open a file which does not exist in "read" mode.

5 Answers

Using pathlib you can check with Path.is_file() which returns True when it encounters a file or a symbolic link to a file.

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}")

This loop should exit when the file isn’t there so you can open it for writing.

you can check if a file exists prior using

os.path.exists(filename)

You could use the OS module to check if the file path is a file, and then open it:

import os

file_path = './file.csv'

if(os.path.isfile(file_path)):
    with open(file_path, "r") as f:

This should work:

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;

You might os.path.exists to check if file already exists for example

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

or harness fact that your names

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

are so regular, exploit glob.glob like so

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