I am making a file open function for the beginning of my program where it prompts the user to input a filename and then it will open that file. I was trying to use the try-except function for this so that if it's a valid file then print it and if its not a valid file to return a filenotfound error. I'm unsure how I can implement the file not found error. This is what I came up with so far:
def open_file():
file = input("Please input a file to use: ")
try:
fp = open(file)
except:
filenotfounderror
I'm pretty sure this should work but I'm not sure what to write in place of the filenotfound error after except
This is how it should be:
def open_file():
file = input("Please input a file to use: ")
try:
fp = open(file)
except FileNotFoundError:
print("File Not Found")
I think the below is what you are looking for
def open_file():
file_name = input("Please input a file to use: ")
try:
fp = open(file_name)
# do something with the file - dont forget to close it
except FileNotFoundError:
print(f"Wrong file or file path: {file_name}")
You don't need try/except for this; Python will raise a FileNotFoundError without your help if the file cannot be found.
What your code would do is replace every other error (permission denied, invalid file name, wrong moon phase over Redmond, etc) with FileNotFoundError. Don't do that (and generally don't use a blanket except, at least until you know exactly what you are doing).
If you want to raise an exception, the keyword for that is raise. For example;
try:
with open(input("File: ")) as inp:
# ... do something
except FileNotFoundError as exc:
print("ooops, we got a", exc)
raise ValueError("Surreptitiously replacing %s" % exc)
Related
I am a total beginner to Python, and am attempting the following exercise:
1) Write code to open and read a file
2) Allow the user to specify a filename
3) Add error handling to allow the user to try again if the file cannot be located
I have tried searching for any related questions prior to this but was unable to resolve the issue below:
import sys
def file_name():
file_name = input("Please choose a filename you wish to open/read: ")
return file_name
def file_reader(file_name):
try:
while file_name.find(".") < 0:
file_name += ".txt"
read_mode = "r"
with open(file_name, read_mode) as file:
output = "\n" + file.read() + "\n"
return output
except FileNotFoundError:
print("\nFILE NOT FOUND! Please try again.\n")
print_contents()
except:
error = sys.exc_info()[0]
print("Many apologies! Something has went wrong!")
print(error)
def print_contents():
print(file_reader(file_name()))
while True:
print_contents()
Here, the function "file_reader(file_name)" concatenates ".txt" to the end of the user-specified filename where there is no file extension already specified, then attempts to read from the file.
In the event of a FileNotFoundError exception, this then prompts the user for another input.
However, if the user then enters a valid filename after the exception, the file contents are returned, followed by 'None'.
I am very confused as to why 'None' is returned with the file contents ONLY ONCE after a FileNotFoundError exception has been handled, after which the 'while True' loop seems to work correctly again. How can I prevent 'None from being returned with the user-specified file data after a FileNotFoundError exception was previously handled?
As I am still very new to Python, any other constructive feedback is welcomed.
I am trying to read a file as follows and I want to log an error if the file does not exist. So I wrote the following code. But this code does not go into the except block at all. I don't have the file for sure.
DEFAULT_ROLE_PROPERTIES = '/tmp/role.properties'
try:
self.role_properties = os.environ.get('VAULT_ROLE_PROPERTIES', DEFAULT_ROLE_PROPERTIES)
with open(self.role_properties, 'r') as rolefp:
cfg.readfp(rolefp)
self.role_id = cfg.get('region', 'role_id')
except Exception as msg:
self.log.error("Unable to read role properties")
I am not sure what is wrong with the syntax here. The above code is in an init function (constructor) could that be the issue?
ls /tmp/role.properties
ls: cannot access /tmp/role.properties: No such file or directory
You could use os.path to check that the path exists (first) before proceeding with getting environment/other attributes
Sample code:
import os.path
os.path.exists('tmp/role.properties/')
If you were checking to see if a particular file was present, and valid (not empty) you could use os.stat
try:
if os.stat(filename).st_size > 0:
print "file present"
else:
print "file present but empty"
except OSError:
print "No file"
Hope this helps
I'm attempting to write error handling in Python 2.7 for when an IOError exception is raised after a user enters a filename.
I have tried a couple of solutions our there on the internet including:
How to retry after exception?
Get a Try statement to loop around until correct value obtained
This is my original code:
while True:
try:
with open (userFile, 'r') as txtFile:
for curLine in txtFile:
curLine = curLine.rstrip("\n\r")
idList.append(curLine)
except IOError:
print("File does not exist")
Whenever the IOError exception is raised it goes into an infinite loop, printing "File does not exist" over and over again. In the instance where I limit the attempts by adding a range, it goes through that range, printing over and over again and then exits the script. Does anyone have an idea why this keeps looping when the exception is raised?
This will be much easier if you split the separate concerns into functions, i.e. (i) warning the user if a file doesn't exist and (ii) reading the contents of the file into a list of lines:
def read_file(f):
# you can't read a file line-by-line and get line endings that match '\n\r'
# the following will match what your code is trying to do, but perhaps not
# what you want to accomplish..?
return f.read().split("\n\r") # are you sure you haven't switched these..?
def checked_read_file(fname):
try:
with open(fname, 'rb') as fp: # you'll probably need binary mode to read \r
return read_file(fp)
except IOError:
print("File does not exist")
return False
then you can write your while loop:
while True:
result = checked_read_file(user_file)
if result is not False: # this is correct since the empty list is false-y
break
user_file = input("Enter another filename: ") # or user_file = raw_input("...: ") if you're on Python 2
# here result is an array of lines from the file
I have been learning and practicing python and during which
I found one error in my program, but I'm unable to resolve. I want to return list of that is retrieved from a csv file. I tried the below code and it returns me an error.
import csv
def returnTheRowsInTheFile(fileName):
READ = 'r'
listOfRows = []
try:
with open(fileName, READ) as myFile:
listOfRows = csv.reader(myFile)
return listOfRows
except FileNotFoundError:
print('The file ' + fileName + ' is not found')
except:
print('Something went wrong')
finally:
#myFile.close()
print()
def main():
fullString = returnTheRowsInTheFile('ABBREVATIONS.CSV')
for eachRow in fullString:
print(eachRow)
return
main()
And the error is
Traceback (most recent call last): File
"C:\Users\santo\workspace\PyProject\hello\FinalChallenge.py", line 36,
in
main() File "C:\Users\santo\workspace\PyProject\hello\FinalChallenge.py", line 32,
in main
for eachRow in fullString: ValueError: I/O operation on closed file.
The easy way to solve this problem is to return a list from your function. I know you assigned listOfRows = [] but this was overwritten when you did listOfRows = csv.reader(myFile).
So, the easy solution is:
def returnTheRowsInTheFile(fileName):
READ = 'r'
try:
with open(fileName, READ) as myFile:
listOfRows = csv.reader(myFile)
return list(listOfRows) # convert to a list
except FileNotFoundError:
print('The file ' + fileName + ' is not found')
except:
print('Something went wrong')
You should also read pep8 which is the style guide for Python; in order to understand how to name your variables and functions.
When you use with open it closes the file when the context ends. Now listOfRows is of the return type of csv.Reader, and so is then fullString (not a list). You are trying to iterate on it, which seems to iterate over a file object, which is already closed.
As JulienD already pointed the file is alread closed when you try to read the rows from it. You can get rid of this exception using this for example:
with open(fileName, READ) as myFile:
listOfRows = csv.reader(myFile)
for row in listOfRows:
yield row
UPDATE
Btw the way you handle exceptions makes it pretty hard to debug. I'd suggest something like this.
except Exception as e:
print('Something went wrong: "%s"' e)
This way you can at least see the error message.
I have a function that takes a source file containing times (a csv file), reads it, then sorts the lines in order and writes them in a destination file. However, if the source csv file does not exist, I need to raise a FileNotFoundError. I've raised exceptions before, for example, if a parameter wasn't an integer I had to raise ChangeParameterError by using:
class ChangeParameterError(Exception):
pass
and then raising that in my function.
For my problem, my function is as follows:
def times(src,dst):
s = open(src,'r')
d = open(dst,'w')
lines = s.readlines()
s.close()
lines.sort()
for i in lines:
print((str(i).strip()), file = d)
d.close()
Any help is appreciated!
If the specified file is not found, the FileNotFoundError will be raised automatically by the open call when trying to open the file.
The exception is automatically raised by python. But you may need to wrap your open with a try-except to catch the exception without breaking your code:
try:
s = open(src,'r')
except FileNotFoundError:
print('file not found')