This question already has answers here:
Catching an exception while using a Python 'with' statement
(5 answers)
Closed 8 years ago.
A simple way to open a file and read its contents is using with:
with open ('file.txt', "r") as filehandle:
contents = filehandle.read()
But that does not include excepting file opening errors in a way that a try/except would:
try:
filehandle = open('file.txt', 'r')
contents = filehandle.read()
except IOError:
print('There was an error opening the file!')
sys.exit()
Is there a way to integrate a failure message in the with statement so that it exits gracefully if the opening fails that would be done in fewer lines of code than the second example yet provide the same functionality? If not that, is there anything more elegant (or minimalist) than the second form?
from contextlib import contextmanager
#contextmanager
def safe_open(fname,mode):
try:
fh = open(fname,mode)
except IOError:
print "ERROR OPENING FILE :",fname
sys.exit()
else:
yield fh
try:
fh.close()
except:
pass
with safe_open("nofile","rb") as f:
f.write("blah")
Im not sure that its more elegant but meh ...
Related
Suppose I want to introduce a try-except block while handling a txt file. Which of the two following way of capturing the possible exception is correct?
try:
h = open(filename)
except:
h.close()
print('Could not read file')
try:
h = open(filename)
except:
print('Could not read file')
In other words, should the h.close() be called even if the exception occurs or not?
Secondly, suppose that you have the following code
try:
h = open(filename)
"code line here1"
"code line here2"
except:
h.close()
print('Could not read file')
If an error occurs in "code line here1", should I use h.close() in the except block?
Is there a difference with the previous coding lines?
You should use with, it will close the file appropriately:
with open(filename) as h:
#
# do whatever you need...
#
# when you get here, the file will be closed automatically.
You can enclose that in a try/except block if needed. The file will always be properly closed:
try:
with open(filename) as h:
#
# do whatever you need...
#
except FileNotFoundError:
print('file not found')
I'm trying to control exceptions when reading files, but I have a problem. I'm new to Python, and I am not yet able to control how I can catch an exception and still continue reading text from the files I am accessing. This is my code:
import errno
import sys
class Read:
#FIXME do immutables this 2 const
ROUTE = "d:\Profiles\user\Desktop\\"
EXT = ".txt"
def setFileReaded(self, fileToRead):
content = ""
try:
infile = open(self.ROUTE+fileToRead+self.EXT)
except FileNotFoundError as error:
if error.errno == errno.ENOENT:
print ("File not found, please check the name and try again")
else:
raise
sys.exit()
with infile:
content = infile.read()
infile.close()
return content
And from another class I tell it:
read = Read()
print(read.setFileReaded("verbs"))
print(read.setFileReaded("object"))
print(read.setFileReaded("sites"))
print(read.setFileReaded("texts"))
Buy only print this one:
turn on
connect
plug
File not found, please check the name and try again
And no continue with the next files. How can the program still reading all files?
It's a little difficult to understand exactly what you're asking here, but I'll try and provide some pointers.
sys.exit() will terminate the Python script gracefully. In your code, this is called when the FileNotFoundError exception is caught. Nothing further will be ran after this, because your script will terminate. So none of the other files will be read.
Another thing to point out is that you close the file after reading it, which is not needed when you open it like this:
with open('myfile.txt') as f:
content = f.read()
The file will be closed automatically after the with block.
For instance, I have a function like:
def example():
fp = open('example.txt','w+')
fp.write(str(1/0))
fp.close()
Then it will throw an exception because 1/0 is not defined. However, I can neither remove example.txt nor modify example.txt. But I have some important data in Python, so that I can't simply kill Python and run it again.
How could I finish opening the file when the function finish with an exception.
What shall we do if we didn't place a try:.. except:.. ?
with open('example.txt','w+') as fp:
try:
fp.write(...)
except ZeroDivisionError as e:
print('there was an error: {}'.format(e))
Using the with context manager any files opened by it will be closed automatically once they go out of scope.
You can wrap that in a try/except to handle the error and close the file reader before the program ends.
def example():
fp = open('example.txt', 'w+')
try:
fp.write(str(1/0))
except ZeroDivisionError:
fp.close()
fp.close()
Edit: The answer by #IanAuld is better than mine. It would be best to accept that one.
I am browsing URL using txt file follow.txt and doing click on specific button in website.But the problem is that sometime I am getting error of unable to locate element and unable to click button.
I want that if that error come, it should read second line of txt file and ignore the error.I also tried the code to overcome the problem.But it is still not working properly.I think my code have some problem.How i can solve this problem.Here is my code that i used for error handling.
try:
f = open('follow.txt', 'r', encoding='UTF-8', errors='ignore')
line = f.readline()
while line:
line = f.readline()
browser.get(line)
browser.find_element_by_xpath(""".//*[#id='react-root']/section/main/article/header/div[2]/div[1]/span/button""").click()
time.sleep(50)
f.close();
except Exception as e:
f = open('follow.txt', 'r', encoding='UTF-8', errors='ignore')
line = f.readline()
while line:
line = f.readline()
browser.get(line)
browser.find_element_by_xpath(""".//*[#id='react-root']/section/main/article/header/div[2]/div[1]/span/button""").click()
time.sleep(20)
browser.find_element_by_tag_name("body").send_keys(Keys.ALT + Keys.NUMPAD2)
browser.switch_to_window(main_window)
time.sleep(10)
f.close();
In the way you have written the answer to a question like... "What happens when there is an error even in the second line?" would be scary. You definitely do NOT want to write as many nested try except blocks as the number of lines in the file.
So, you will need to have the try except on the statement where you would expect an error, which will allow you to use the opened file object without the necessity to reopen the file. Something similar to the following:
f = open('follow.txt', 'r', encoding='UTF-8', errors='ignore')
line = f.readline()
while line:
line = f.readline()
browser.get(line)
try:
browser.find_element_by_xpath(""".//*[#id='react-root']/section/main/article/header/div[2]/div[1]/span/button""").click()
except Exception as e:
print e # Or better log the error
time.sleep(50)
browser.find_element_by_tag_name("body").send_keys(Keys.ALT + Keys.NUMPAD2)
browser.switch_to_window(main_window)
time.sleep(10)
f.close();
This should let you to continue with the next line even though there is an error at the time of ".click()". Note that you do not want to close the file when you are not done with reading all that you want from file.
My intention of moving "try except" deep into the logic doesn't mean that you shouldn't use "try except" else where for example while opening file. The more better way is to use 'with' in which case you don't even need to worry about closing the file and handling exceptions while opening the file.
with open('follow.txt', 'r', encoding='UTF-8', errors='ignore') as f:
....
I am going to start of by showing the code I have thus far:
def err(em):
print(em)
exit
def rF(f):
s = ""
try:
fh = open(f, 'r')
except IOError:
e = "Could not open the file: " + f
err(e)
try:
with fh as ff:
next(ff)
for l in ff:
if ">" in l:
next(ff)
else:
s += l.replace('\n','').replace('\t','').replace('\r','')
except:
e = "Unknown Exception"
err(e)
fh.close()
return s
For some reason the python shell (I am using 3.2.2) freezes up whenever I tried to read a file by typing:
rF("mycobacterium_bovis.fasta")
The conditionals in the rF function are to prevent reading each line that starts with a ">" token. These lines aren't DNA/RNA code (which is what I am trying to read from these files) and should be ignored.
I hope anyone can help me out with this, I don't see my error.
As per the usual, MANY thanks in advance!
EDIT:
*The problem persists!*
This is the code I now use, I removed the error handling which was a fancy addition anyway, still the shell freezes whenever attempting to read a file. This is my code now:
def rF(f):
s = ""
try:
fh = open(f, 'r')
except IOError:
print("Err")
try:
with fh as ff:
next(ff)
for l in ff:
if ">" in l:
next(ff)
else:
s += l.replace('\n','').replace('\t','').replace('\r','')
except:
print("Err")
fh.close()
return s
You didn't ever define e.
So you'll get a NameError that is being hidden by the naked except:.
This is why it is good and healthy to specify the exception, e.g.:
try:
print(e)
except NameError as e:
print(e)
In cases like yours, though, when you don't necessarily know what the exception will be you should at least use this method of displaying information about the error:
import sys
try:
print(e)
except: # catch *all* exceptions
e = sys.exc_info()[1]
print(e)
Which, using the original code you posted, would have printed the following:
name 'e' is not defined
Edit based on updated information:
Concatenating a string like that is going to be quite slow if you have a large file.
Consider instead writing the filtered information to another file, e.g.:
def rF(f):
with open(f,'r') as fin, open('outfile','w') as fou:
next(fin)
for l in fin:
if ">" in l:
next(fin)
else:
fou.write(l.replace('\n','').replace('\t','').replace('\r',''))
I have tested that the above code works on a FASTA file based on the format specification listed here: http://en.wikipedia.org/wiki/FASTA_format using Python 3.2.2 [GCC 4.6.1] on linux2.
A couple of recommendations:
Start small. Get a simple piece working then add a step.
Add print() statements at trouble spots.
Also, consider including more information about the contents of the file you're attempting to parse. That may make it easier for us to help.