tags:

views:

262

answers:

3

I'm doing it like this now, but i want it to write at the beginning of the file instead.

f = open('out.txt', 'a') # or 'w'?
f.write("string 1")
f.write("string 2")
f.write("string 3")
f.close()

so that the contenst of out.txt will be:

string 3
string 2
string 1

and not (like this code does):

string 1
string 2
string 3
+2  A: 

You could throw a f.seek(0) between each write (or write a wrapper function that does it for you), but there's no simple built in way of doing this.

EDIT: this doesn't work, even if you put a f.flush() in there it will continually overwrite. You may just have to queue up the writes and reverse the order yourself.

So instead of

f.write("string 1")
f.write("string 2")
f.write("string 3")

Maybe do something like:

writeList = []
writeList.append("string 1\n")
writeList.append("string 2\n")
writeList.append("string 3\n")
writeList.reverse()
f.writelines(writeList)
Daniel DiPaolo
A: 

Elaborating on Daniel DiPaolo's answer:

Simply append all the lines that you want to write to a list. Reverse the list and then write its contents into the file.

f=open('output.txt','w')

l=[]
l.append("string 1")
l.append("string 2")
l.append("string 3")

for line in l:
    f.write(line)

f.close()

You could also use a deque and add lines at its beginning instead of using a list and reversing it.

MAK
What if the usage for this was more like a log file, where the script may write to the log on successive executions? Is the only recourse to hold the entire file in memory, seek to the beginning to write your stuff followed by all the previous contents? (excluding creating intermediate files)
Nick T
I'm not aware of anything in Python's `file` class that allows for something like this directly (i.e. without using some sort of intermediate buffer). So, right now, this looks like the simplest way. For a log file, wouldn't it make a lot more sense and make life a lot simpler simply to append the newest entries to the end of the file?
MAK
@Nick, @MAK, Not only is there nothing in Python that can handle this, there's nothing in the underlying C library or the filesystem. This is simply not how files operate, and you can't grow a file other than by appending unless you're willing to copy the content around. It could be done with a new file, or by moving data within the old file, but either way it's very likely a bad idea. Better change the requirements or the way you view the problem...
Peter Hansen
+1  A: 

Take a look at this question. There are some solutions there.

Though I would probably go that same way Daniel and MAK suggest -- maybe make a lil' class to make things a little more flexible and explicit:

class front_appender:
    def __init__(self, fname, mode='w'):
        self.__f = open(fname, mode)
        self.__write_queue = []

    def write(self, s):
        self.__write_queue.insert(0, s)

    def close(self):
        self.__f.writelines(self.__write_queue)
        self.__f.close()

f = front_appender('test_d.out')
f.write('string 1\n')
f.write('string 2\n')
f.write('string 3\n')
f.close()
kaloyan