Recently I've been practicing lessions by Jason Cannon on O'reilly: https://learning.oreilly.com/videos/python-for-beginners/9781789617122/9781789617122-video10_3/
At 6:55 of the 'Files, Part II' section, I have a problem practicing error catch following the idea in the video. My code:
with open('data.txt') as file:
try:
file_content = file.read()
except:
file_content = ''
print(len(file_content))
The idea is to catch error when the file is not found, the try block runs but the except block not. I expected the file_content has length of 0 instead of error shows up. Please tell me where I did wrong. Thank you very much
If the file isn't found, it's open that raises the error, not the attempt to read from it.
try:
with open('data.txt') as file:
file_content = file.read()
except (FileNotFoundError, IOError):
file_content = ''
Note that if open raises a FileNotFound error, then no context manager will actually be created, and so there is no need for the with statement to try to execute an __exit__ method before control passes to the exception handler.
Related
I have a script which wants to load integers from a text file. If the file does not exist I want the user to be able to browse for a different file (or the same file in a different location, I have UI implementation for that).
What I don't get is what the purpose of Exception handling, or catching exceptions is. From what I have read it seems to be something you can use to log errors, but if an input is needed catching the exception won't fix that. I am wondering if a while loop in the except block is the approach to use (or don't use the try/except for loading a file)?
with open(myfile, 'r') as f:
try:
with open(myfile, 'r') as f:
contents = f.read()
print("From text file : ", contents)
except FileNotFoundError as Ex:
print(Ex)
You need to use to while loop and use a variable to verify in the file is found or not, if not found, set in the input the name of the file and read again and so on:
filenotfound = True
file_path = myfile
while filenotfound:
try:
with open(file_path, 'r') as f:
contents = f.read()
print("From text file : ", contents)
filenotfound = False
except FileNotFoundError as Ex:
file_path = str(input())
filenotfound = True
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.