File Open Function with Try & Except Python 2.7.1 - python

def FileCheck(fn):
try:
fn=open("TestFile.txt","U")
except IOError:
print "Error: File does not appear to exist."
return 0
I'm trying to make a function that checks to see if a file exists and if doesn't then it should print the error message and return 0 . Why isn't this working???

You'll need to indent the return 0 if you want to return from within the except block.
Also, your argument isn't doing much of anything. Instead of assigning it the filehandle, I assume you want this function to be able to test any file? If not, you don't need any arguments.
def FileCheck(fn):
try:
open(fn, "r")
return 1
except IOError:
print "Error: File does not appear to exist."
return 0
result = FileCheck("testfile")
print result

I think os.path.isfile() is better if you just want to "check" if a file exists since you do not need to actually open the file. Anyway, after open it is a considered best practice to close the file and examples above did not include this.

This is likely because you want to open the file in read mode.
Replace the "U" with "r".
Of course, you can use os.path.isfile('filepath') too.

If you just want to check if a file exists or not, the python os library has solutions for that such as os.path.isfile('TestFile.txt'). OregonTrails answer wouldn't work as you would still need to close the file in the end with a finally block but to do that you must store the file pointer in a variable outside the try and except block which defeats the whole purpose of your solution.

Related

Python File Remains Empty After Writing to it Issue

I am trying to read URL directly from MYSQLDB table and tldextract to get the domain from the url and find the SPF(Sender Policy Framework) Record for the domain.
When i'm trying to write the SPF records of each and every domain i scan,My Ouput_SPF_Records.txt do not contain any records i write.
Not sure with the issue,Any suggestions please ?
import sys
import socket
import dns.resolver
import re
import MySQLdb
import tldextract
from django.utils.encoding import smart_str, smart_unicode
def getspf (domain):
answers = dns.resolver.query(domain, 'TXT')
for rdata in answers:
for txt_string in rdata.strings:
if txt_string.startswith('v=spf1'):
return txt_string.replace('v=spf1','')
db=MySQLdb.connect("x.x.x.x","username","password","db_table")
cursor=db.cursor()
cursor.execute("SELECT application_id,url FROM app_info.app_urls")
data=cursor.fetchall()
x=0
while x<len(data):
c=tldextract.extract(data[x][1])
#print c
app_id=data[x][0]
#print app_id
d=str(app_id)+','+c[1]+'.'+c[2]
#with open('spfout.csv','a') as out:
domain=smart_str(d)
#print domain
with open('Ouput_SPF_Records.txt','w') as g:
full_spf=""
spf_rec=""
y=domain.split(',')
#print "y===",y,y[0],y[1]
app_id=y[0]
domains=y[1]
try:
full_spf=getspf(domains.strip())+"\n"
spf_rec=app_id+","+full_spf
print spf_rec
except Exception:
pass
g.write(spf_rec)
x=x+1
g.close()
Try openning the file with append mode, instead of w mode. w mode overwrites the file in each iteration. Example -
with open('Ouput_SPF_Records.txt','a') as g:
Most probably, the last time you open the file in write mode, you do not write anything in since, you are catching and ignoring all exceptions , which causes the empty file.
Also, if you know the error which you are expecting, you should use except <Error>: instead of except Exception: . Example -
try:
full_spf=getspf(domains.strip())+"\n"
spf_rec=app_id+","+full_spf
print spf_rec
except <Error you want to catch>:
pass
Your problem is you open the file many times, each time through the loop. You use w mode, which erases the contents and writes from the beginning.
Either open the file once before the loop, or open in append mode a, so you don't delete the previously written data.
You can use :
import pdb;pdb.set_trace()
Debug your code and try to figure out the problem.
also note that :
1. You shouldn't just write 'pass' in the try/except block. Deal with the Exception
2.
with open('Ouput_SPF_Records.txt','w') as g:
it will automatically close the file, so there is no need to do : g.close() explicitly.
I think this is the result of getspf return None by default.
The Problem is that python cant concatenate str and NoneType (the type of None) (which throws an exception that you quickly discard).
You may try this instead:
def getspf (domain):
answers = dns.resolver.query(domain, 'TXT')
for rdata in answers:
for txt_string in rdata.strings:
if txt_string.startswith('v=spf1'):
return txt_string.replace('v=spf1','')
return ""#"Error"
Probably you should check for the exception, my guess is that statements inside it are not performed, and spf_rec is left to "".
As per POSIX definition (http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_206), every line you write should end with "\n".
You might considering to initialise spf_rec with "\n" rather than "".
Also, as "Anand S Kumar" said, without an append, the file is overwritten at every "while x
I think that if you open the Ouput_SPF_Records.txt file with "vi", you will see the last line written (unless an exception occurred on the last execution of the cycle, causing the file to be just "").
In other words, the problem is that many software may not read a line that doesn't respect the POSIX standard, and because your file is probably composed by a unique line that doesn't respect this standard, the file won't be read at all.

Looping function to ask for input until valid

I have this function:
def read_file(fname):
f = open(fname, 'r')
s = f.read()
return s
It is supposed to take an input(the name of the file to read) and save it to a variable called portfolio. However, if I specify a file that does not exist, I get an IOError, and I can't seem to figure out how to deal with it through try/except.
Any ideas?
You can't stop it from giving you the IOError for a nonexistent file. If you could, how would you even know that you had to do anything, like ask for another filename?
What you can do is deal with that error—in any way you want, like asking for another filename.
For example:
while True:
fname = raw_input('Gimme a filename')
try:
contents = read_file(fname)
break
except IOError as e:
print('Sorry, {} gives me an error: {}'.format(fname, e))
Now, when you run this, it'll keep asking for a filename until you give it one that you can read. If you give it a file that doesn't exist (or one that you don't have read permissions for, or that's locked for exclusive access, or that's stored on a bad disk block, or anything else that can cause an error), it'll ask you again.
Why not just do this?
success = 0
while (success == 0):
try:
#get your input
read_file(fname)
success = 1
except(IOError):
success = 0 #totally unnecessary I guess, but whatever
It's been a while since I did real development, so that might not be how try/except actually works in Python, but you get the idea.

Restore original file in case of an error

I need to write data to a file and overwrite it if file exists. In case of an error my code should catch an exception and restore original file (if applicable)
How can I restore file? Should I read original one and put content i.e. in a list and then in case of an exception just write this list to a file?
Are there any other options? Many thanks if anyone can provide some kind of an example
Cheers
The code below will make a copy of the original file and set a flag indicating if it existed before or not. Do you code in the try and if it makes it to the end it will set the worked flag to True and your are go to go otherwise, it will never get there, the exception will still be raised but the finally will clean up and replace the file if it had existed in the first place.
import os
import shutil
if os.path.isfile(original_file):
shutil.copy2(original_file, 'temp' + original_file)
prev_existed = True
else:
prev_existed = False
worked = False
try:
with open(original_file, 'w') as f:
## your code
worked = True
except:
raise
finally:
if not worked and prev_existed:
shutil.copy2('temp' + original_file, original_file)
Any attempt to restore on error will be fragile; what if your program can't continue or encounters another error when attempting to restore the data?
A better solution would be to not replace the original file until you know that whatever you're doing succeeded. Write whatever you need to to a temporary file, then when you're ready, replace the original with the temporary.
One way to do it is the append the new data at the end of the existing file. If you catch an error , delete all that you appended.
If no errors, delete everything that you had before appending so the new file will have only the appended data.
Create a copy of your file before starting capturing the data in a new file.

Don't save empty file

I create a new text file with f = open('file.txt', 'w'). Then, as I go about to get stuff to write on it, there is a problem and I need to exit without actually writing anything.
However, the file is still created, but empty. Is there a way to keep the file from being saved in case nothing is going to be written on it, or do I have to explicitly delete it in case something goes wrong?
You can use atexit to simulate this behavior, but there's probably a Better Way out there somewhere.
import atexit
def safety_trigger():
try:
os.remove(FILENAME)
except FileNotFoundError:
pass
atexit.register(safety_trigger)
with open(FILENAME,'w') as f:
# do your
# file operations
atexit.unregister(safety_trigger)
This way when your script starts, you set it to automatically delete FILENAME when it ends. Once you're done writing to the file, you tell your script NOT to automatically delete FILENAME when it ends.
You could simply prepare the information for writing first and only perform the saving and such if it makes it through preparation without a hitch.
info_to_write = ""
try:
info_to_write += "something!"
# etc...
if something_went_wrong:
raise Exception
with open("file.txt","w") as f:
f.write(info_to_write)
catch:
print "Nothing written, no file created"

How to make sure a file exists or can be created before writing to it in Python?

I'm writing a function and I want it to touch a file so that I can write to that file. If the file doesn't exist, I will get an error. How can I say that?
Just open the file for writing and it will be created if it doesn't exist (assuming you have proper permission to write to that location).
f = open('some_file_that_might_not_exist.txt', 'w')
f.write(data)
You will get an IOError if you can't open the file for writing.
Per the docs, os.utime() will function similar to touch if you give it None as the time argument, for example:
os.utime("test_file", None)
When I tested this (on Linux and later Windows), I found that test_file had to already exist. YMMV on other OS's.
Of course, this doesn't really address writing to the file. As other answers have said, you usually want open for that and try ... except for catching exceptions when the file does not exist.
if you actually want to raise an error if the file doesn't exist, you can use
import os
if not os.access('file'):
#raise error
f = open('file')
#etc.

Categories

Resources