Reputation: 690
I have a python project for a GUI to be used with the slurm queuing manager at our computing cluster. One thing I can do is to print the contents of certain files for a specific job in a text window.
However, the extensions people use for the same type of file will sometimes change. I could program it such that it works for me, but I also want to be able to look up other people's files.
The way I have solved this is the following
extensions = [".ex1", ".ext2", "ext3"]
for ext in extensions:
try:
f = open(jobname+ext), "r")
content = f.read()
f.close()
<doing some stuff with content>
except IOError:
if ext == extensions[-1]:
print("File not found")
return
If the actual extension used is covered by extensions
, then my code will find it. I would like to know if more experienced programmers have a better/more elegant/more efficient way of doing it. Luckily the files to be read are very small, so looping over all the possibilities will not take much time. But this particular solution might not be suitable for other cases.
Upvotes: 1
Views: 75
Reputation: 1169
As I understand the Question, you already know the filename and path, and only the extension is unknown.
Use the glob
package to find all files with that name like this:
from glob import glob
matches = glob("/path/to/files/knownfilename.*")
if not matches:
print("File not found!")
return
try:
with open(matches[0], "r") as f:
content = f.read()
# do stuff
except IOError:
print("Error reading file {}".format(matches[0]))
In this case you might have to deal with the possibility that
matches
list is not the kind of file you want (maybe some backup file with .bak extension or whatever), so you might also want to blacklist some extensionsUpvotes: 1
Reputation: 4689
Even if that works, the logic of comparing the current extension with the end of the list feels weird. In the worst case, if the last extension is accidentally duplicated earlier in the list, this would lead to hard-to-diagnose errors.
Since (presumably) you already return out of the loop as soon as you have found the file, you could just put the "missing-file" behavior after the loop (where it will only be reached if no file was found), and leave the catch-block empty:
extensions = [".ex1", ".ext2", ".ext3"]
for ext in extensions:
try:
with open(jobname+ext), "r") as f:
content = f.read()
<doing some stuff with content>
return
except IOError:
pass
print("File not found")
Upvotes: 0
Reputation: 106455
You can use os.listdir('.')
to get a list of file names in the current working directory, iterate through the list with a for
loop, and slice the file name from the length of jobname
and use the in
operator to test if it is one of extension names in the extensions
list/tuple. break
after processing the file when a file is found with the desired name. Use the else
block for the for
loop to print a File not found
message if the loop finishes without breaking:
import os
extensions = '.ext1', '.ext2', '.ext3'
for filename in os.listdir('.'):
if filename.startswith(jobname) and filename[len(jobname):] in extensions:
with open(filename) as f:
content = f.read()
# doing some stuff with content
break
else:
print("File not found")
Upvotes: 0
Reputation: 149736
You could use the with
statement to open a file and then have it automatically closed. Also, you could omit the mode parameter to open()
(which defaults to 'r'
) and probably add a break
after you found a valid extension:
extensions = [".ex1", ".ext2", "ext3"]
for ext in extensions:
try:
with open(jobname+ext)) as f:
content = f.read()
# do some stuff with content
break
except IOError:
if ext == extensions[-1]:
print("File not found")
return
Upvotes: 0