Closing opened files? - python

I forgot how many times I opened the file but I need to close them I added the txt.close and txt_again.close after I opened it at least 2 times
I'm following Zed A. Shaw Learn Python The Hard Way
#imports argv library from system package
from sys import argv
#sets Variable name/how you will access it
script, filename = argv
#opens the given file from the terminal
txt = open(filename)
#prints out the file name that was given in the terminal
print "Here's your file %r:" % filename
#prints out the text from the given file
print txt.read()
txt.close()
#prefered method
#you input which file you want to open and read
print "Type the filename again:"
#gets the name of the file from the user
file_again = raw_input("> ")
#opens the file given by the user
txt_again = open(file_again)
#prints the file given by the user
print txt_again.read()
txt_again.close()

In order to prevent such things, it is better to always open the file using Context Manager with like:
with open(my_file) as f:
# do something on file object `f`
This way you need not to worry about closing it explicitly.
Advantages:
In case of exception raised within with, Python will take care of closing the file.
No need to explicitly mention the close().
Much more readable in knowing the scope/usage of opened file.
Refer: PEP 343 -- The "with" Statement. Also check Trying to understand python with statement and context managers to know more about them.

Related

reading from a NamedTemporaryFile in python

I am creating a tempFile and then adding text to it by opening it with an editor(so that user can enter his message), and then save it to read the text from save NamedTemporaryFile.
with tempfile.NamedTemporaryFile(delete=False) as f:
f.close()
if subprocess.call([editor.split(" ")[0], f.name]) != 0:
raise IOError("{} exited with code {}.".format(editor.split(" ")[0], rc))
with open(f.name) as temp_file:
temp_file.seek(0)
for line in temp_file.readlines():
print line
But every time it is coming out to be blank. why is it so ?
If you are using SublimeText as the editor, you will need to pass in the -w or --wait argument to make sure that the Python program waits until you actually close SublimeText again.
Otherwise, you would just start to edit the file, and immediately try to read its contents which at that point are empty.
You could also verify that, by putting in a print before reading the file.
E.g.:
editor = ['/path/to/sublime_text', '-w']
with tempfile.NamedTemporaryFile(delete=False) as f:
f.close()
if subprocess.call(editor + [f.name]) != 0:
raise IOError()
# read file…
Here's a solution without editor interaction since I don't have enough information to mimic your editor setup.
import tempfile
with tempfile.NamedTemporaryFile(delete=False) as f:
f.close()
with open(f.name, f.mode) as fnew:
# Replace with editor interaction
fnew.write('test')
fnew.seek(0)
for line in fnew.readlines():
print line
At least on my system and version (2.7.2), I had to make these changes to allow the file object to be properly reopened and interacted with, and it builds correctly in Sublime. f.name is the temporary file path, and f.mode is the mode used by the already closed file (in this case it should default to 'w+b').

Open a file without getOpenFileName?

is there a way to open files without using QFileDialog.getOpenFileName parameter? The thing is, I have a some buttons that upon clicking them, a notepad will pop up in which you can type anything into the notepad. Then, you can save whatever you wrote in that notepad as a text file. What I want to do is, if I click the button again, I will reopen the file that I had previously edited via the notepad and can continue typing where I left off. However, I don't want to use getOpenFileName. Would it be possible to open a file without using this functionality? Below is my attempt but my if statement keeps evaluating to be false. If anyone could help that would be great. Thanks!
#Testing if the file already exists
if(os.path.exists("~/Desktop/" +self.fileName + ".txt")):
f = open(self.fileName + ".txt", 'r')
filedata = f.read()
self.text.setText(filedata)
f.close()
#Opens a new notepad if there wasn't a previous fileconstructed
else:
self.textBox = textBoxWindow(self.fileName)
self.textBox.show()
If you are on Winsows (you said the word Notepad), you can use the subprocess module to open any file with whatever program currently associated with the file type as follows:
import subprocess
self.filename = r'C:\test.txt'
subprocess.call(['start', self.filename], shell=True)
But the shell=True argument is kinda dangerous, especially of the filename comes as an input.
you can use the webbrowser module too, though not supported use of it I guess:
import webbrowser
webbrowser.open(self.filename)

Text file Trauma in Python

I know this is basic but it has been nagging me for a while now. I am new to Python coding so please have patience.
I am using a Python script to read from MySQL and relay this information to a .txt file using the first line of an existing text file as the name of the new one. All of the MySQL stuff is working fine but I have a problem writing to the .txt file. Code is below:
import MySQLdb
text_file = open("configure.txt","r")
testCamp = (text_file.readline())
print testCamp
text_file.close()
db = MySQLdb.connect(host='localhost',user='username',passwd='password')
cursor = db.cursor()
cursor.execute("SELECT VERSION()")
disp = cursor.fetchone()
print "Database Version: %s " %disp
db.close()
text_file = open(testCamp, "w")
text_file.write("Some Text\n")
input("\n\nPress Enter to Exit.")
As you can see from the code above I am in the process of setting up the framework so I'm not getting any data from the database yet.
The new testCamp file is created ok (although it does not display the .txt extension instead it has some unfamiliar box icon after it). I have checked the file type and it does say it is a normal text file and I have also checked that the permissions allow writing and they do. Interestingly I also tried writing to a text file that was already in place:
text_file = open("Test.txt","w")
text_file.write("Some Text\n")
and it still did not work!
Any suggestions would be appreciated
The readline method on a stream (open file) retains the terminating newline "\n", so if the first line of configure.txt is test.txt, you will be writing to a file named "test.txt\n". Use:
testCamp = testCamp.rstrip()
(after reading the line) to remove all trailing white space (blanks, tabs, newlines), or equivalently:
testCamp = text_file.readline().rstrip()
The write method on a stream opened to a non-interactive file (such as "test.txt" or "test.txt\n") buffers (hangs on to) data. It gets pushed out—"flushed", as in exposing a bird when hunting (see meaning 3 of the verb form of flush)—by invoking the flush method or by closing the stream.
The with context manager will close the stream (as noted in comments and other answers). Use it for reading the configuration file, too (it works for read streams as well as write streams).
You forgot to close your file!
Use this:
text_file.close()
While this is perfectly fine, it is recommended that you use the following format when dealing with file I/O:
with open("filename", "mode(s)") as f:
f.write("Data\n")
So, in your case, that would be:
with open(testCamp, "w") as text_file:
text_file.write("Some Text\n")
And why use with? Read the following:
What is the python "with" statement designed for?
UPDATE 1:
As per #SukritKalra's suggestion, if you're using the context manager via with as shown, you don't need to close the file, that is taken care of for you.
UPDATE 2:
#Torek's answer is correct too, in that if you're using readline, you should strip the line before using it verbatim as the name of a file.

Reading command Line Args

I am running a script in python like this from the prompt:
python gp.py /home/cdn/test.in..........
Inside the script i need to take the path of the input file test.in and the script should read and print from the file content. This is the code which was working fine. But the file path is hard coded in script. Now I want to call the path as a command line argument.
Working Script
#!/usr/bin/python
import sys
inputfile='home/cdn/test.in'
f = open (inputfile,"r")
data = f.read()
print data
f.close()
Script Not Working
#!/usr/bin/python
import sys
print "\n".join(sys.argv[1:])
data = argv[1:].read()
print data
f.close()
What change do I need to make in this ?
While Brandon's answer is a useful solution, the reason your code is not working also deserves explanation.
In short, a list of strings is not a file object. In your first script, you open a file and operate on that object (which is a file object.). But writing ['foo','bar'].read() does not make any kind of sense -- lists aren't read()able, nor are strings -- 'foo'.read() is clearly nonsense. It would be similar to just writing inputfile.read() in your first script.
To make things explicit, here is an example of getting all of the content from all of the files specified on the commandline. This does not use fileinput, so you can see exactly what actually happens.
# iterate over the filenames passed on the commandline
for filename in sys.argv[1:]:
# open the file, assigning the file-object to the variable 'f'
with open(filename, 'r') as f:
# print the content of this file.
print f.read()
# Done.
Check out the fileinput module: it interprets command line arguments as filenames and hands you the resulting data in a single step!
http://docs.python.org/2/library/fileinput.html
For example:
import fileinput
for line in fileinput.input():
print line
In the script that isn't working for you, you are simply not opening the file before reading it. So change it to
#!/usr/bin/python
import sys
print "\n".join(sys.argv[1:])
f = open(argv[1:], "r")
data = f.read()
print data
f.close()
Also, f.close() this would error out because f has not been defined. The above changes take care of it though.
BTW, you should use at least 3 chars long variable names according to the coding standards.

Saving data into a text file

def ConvertFile():
FileNameIn = 'Hexdata.dat'
HexFile = open(FileNameIn, 'r')
for Line in HexFile:
print (Line)
print (Binary(Line))
HexFile.close()
So far I have that, which, when the program is run, converts the Hexidecimal number in the file to binary. This is in a file called Hexdata.dat
What I want to do is then save the binary output into a file called Binarydata.dat
How would I approach this in code? Be aware I'm new with Python and haven't covered this properly. I've tried different bits of code but they've all been unsuccessful, as really, they're all guesses.
I'm not asking you to solve the problem for me, but more asking how I would save the output of a program into a new text file.
You're already most of the way there. You already know how to open a file for reading:
HexFile = open(FileNameIn, 'r')
The 'r' there means "open for reading". If you look at the documentation for the open function, you will see that replacing the r with a w will open a file for writing:
OutputFile = open(FileNameOut, 'w')
And then you can send output to it like this:
print >>OutputFile, "Something to print"
Or use the write method on the file object:
OutputFile.write("Something to print\n")
Read the documentation of the open function (to open the file in write mode) and File Objects (to write information to the opened file).
You have to have 2 files in this script. The one you're reading from and the one you're writing to. Use the option wb (write binary) when opening the file you are going to write into. These two links should help a beginner with little or no Python knowledge complete your exercise: Intro to File Objects and Tutorial on File I/O.
You are currently opening the file in reading mode, so in order to write to the file, you would want to open the file with the buffering mode as ('w'). Quote from: http://docs.python.org. You can do so easily by replacing your 'r' with 'w'.
'w' for writing (truncating the file if it already exists
For more reference see open(name[, mode[, buffering]])
# the file name
FileNameIn = 'Hexdata.dat'
# create a file object: open it with "write" mode
HexFile = open(FileNameIn,"w")
for line in HexFile:
HexFile.write(Binary(line))
HexFile.close()
Have you tried using open('Binarydata.dat', 'w') for writing to the file? There are plenty of ways to write to a file, most of which can be found here: http://docs.python.org/tutorial/inputoutput.html

Categories