2010-04-20 79 views
18

現在我正在這樣做,但我希望它在文件的開頭寫入。write()在文件的開頭?

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

,這樣的out.txt內容將是:

string 3 
string 2 
string 1 

,而不是(像這個代碼):

string 1 
string 2 
string 3 

回答

12

看看this question。那裏有一些解決方案。

雖然我可能會走同樣的路丹尼爾和MAK建議 - 也許做一個可愛的」類讓事情變得更靈活一點,並明確:

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') 
7

你可以扔每次寫之間的f.seek(0)(或寫一個包裝函數可以幫你實現),但是沒有簡單的方法來完成這個任務。

編輯:這不起作用,即使你把f.flush()在那裏,它會不斷覆蓋。您可能只需排隊寫入並自行反轉訂單。

所以不是

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

也許這樣做:

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

在闡述丹尼爾·戴保羅的回答是:

所有要寫入list線只需追加。反轉list,然後將其內容寫入文件。

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() 

你也可以使用一個deque,並在其開始而不是使用list和扭轉其添加行。

+0

如果這個用法更像日誌文件,那麼腳本可能會在連續執行時寫入日誌呢?唯一的辦法是將整個文件保存在內存中,尋求開始寫你的東西,然後是所有以前的內容? (不包括創建中間文件) – 2010-04-20 18:49:37

+0

我不知道Python的'file'類中有什麼東西可以直接使用這種類型(即不使用某種中間緩衝區)。所以,現在看起來這是最簡單的方法。對於一個日誌文件,它是否會變得更有意義,讓生活變得簡單很多,只需將最新的條目追加到文件末尾? – MAK 2010-04-20 19:13:54

+0

@Nick,@MAK,不僅在Python中沒有任何東西可以處理這個問題,底層C庫或文件系統中沒有任何東西。這不僅僅是文件的操作方式,除非您願意複製內容,否則您不能增加文件以外的內容。它可以通過一個新文件來完成,或者通過在舊文件中移動數據來完成,但無論如何這很可能是一個壞主意。更好地改變需求或您查看問題的方式...... – 2010-04-20 23:09:56

1

上kdtrv的答案的變化。此版本保留現有文件內容,並提供保留行順序的write_lines方法。

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', 
     ] 
    )