write() at beginning of file?

2019-01-17 20:54发布

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 contents of out.txt will be:

string 3
string 2
string 1

and not (like this code does):

string 1
string 2
string 3

4条回答
戒情不戒烟
2楼-- · 2019-01-17 21:37

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.

查看更多
beautiful°
3楼-- · 2019-01-17 21:40

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 Prepender:

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

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

    def close(self):
        self.__exit__(None, None, None)

    def __enter__(self):
        return self

    def __exit__(self, type, value, traceback):
        if self.__write_queue: 
            self.__f.writelines(self.__write_queue)
        self.__f.close()

with Prepender('test_d.out') as f:
    f.write('string 1\n')
    f.write('string 2\n')
    f.write('string 3\n')
查看更多
Juvenile、少年°
4楼-- · 2019-01-17 21:41

A variation on kdtrv's answer. This version keeps the existing file contents, and offers a write_lines method that preserves line order.

class Prepender(object):
    def __init__(self,
                 file_path,
                ):
        # Read in the existing file, so we can write it back later
        with open(file_path, mode='r') as f:
            self.__write_queue = f.readlines()

        self.__open_file = open(file_path, mode='w')

    def write_line(self, line):
        self.__write_queue.insert(0,
                                  "%s\n" % line,
                                 )

    def write_lines(self, lines):
        lines.reverse()
        for line in lines:
            self.write_line(line)

    def close(self):
        self.__exit__(None, None, None)

    def __enter__(self):
        return self

    def __exit__(self, type, value, traceback):
        if self.__write_queue:
            self.__open_file.writelines(self.__write_queue)
        self.__open_file.close()


with Prepender('test_d.out') as f:
    # Must write individual lines in reverse order
    f.write_line('This will be line 3')
    f.write_line('This will be line 2')
    f.write_line('This will be line 1')

with Prepender('test_d.out') as f:
    # Or, use write_lines instead - that maintains order.
    f.write_lines(
        ['This will be line 1',
         'This will be line 2',
         'This will be line 3',
        ]
    )
查看更多
The star\"
5楼-- · 2019-01-17 21:51

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)
查看更多
登录 后发表回答