2010-04-20 26 views
18

Tôi đang làm như thế này ngay bây giờ, nhưng tôi muốn nó viết ở đầu tệp thay vào đó.write() ở đầu tệp?

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

để các nội dung của out.txt sẽ là:

string 3 
string 2 
string 1 

và không (như mã này không):

string 1 
string 2 
string 3 

Trả lời

12

Hãy xem this question. Có một số giải pháp ở đó.

Mặc dù tôi có lẽ sẽ đi cùng cách Daniel và MAK gợi ý - có thể làm cho một 'lớp lil để làm cho mọi việc linh hoạt hơn một chút và rõ ràng:

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

Bạn có thể ném một f.seek(0) giữa mỗi ghi (hoặc viết một hàm bao hàm thực hiện nó cho bạn), nhưng không có cách nào đơn giản được xây dựng để làm điều này.

EDIT: tính năng này không hoạt động, ngay cả khi bạn đặt f.flush() ở đó, nó sẽ liên tục ghi đè. Bạn có thể chỉ phải xếp hàng và viết ngược lại.

Vì vậy, thay vì

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

Có lẽ làm một cái gì đó như:

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

Xây dựng về câu trả lời Daniel DiPaolo của:

Đơn giản chỉ cần thêm tất cả các dòng mà bạn muốn viết thư cho một list. Đảo ngược các list và sau đó viết nội dung của nó vào tập tin.

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

Bạn cũng có thể sử dụng một deque và thêm dòng ở đầu của nó thay vì sử dụng một list và đảo ngược nó.

+0

Điều gì xảy ra nếu việc sử dụng tệp này giống như tệp nhật ký, nơi tập lệnh có thể ghi vào nhật ký về các lần thực thi liên tiếp? Là sự truy đòi duy nhất để giữ toàn bộ tập tin trong bộ nhớ, tìm cách bắt đầu để viết công cụ của bạn theo sau bởi tất cả các nội dung trước đó? (không bao gồm việc tạo các tệp trung gian) –

+0

Tôi không biết gì về lớp 'tệp' của Python cho phép trực tiếp điều này (nghĩa là không sử dụng một số loại đệm trung gian). Vì vậy, ngay bây giờ, điều này trông giống như cách đơn giản nhất. Đối với một tập tin nhật ký, nó sẽ không làm cho ý nghĩa hơn rất nhiều và làm cho cuộc sống đơn giản hơn rất nhiều chỉ đơn giản là để thêm các mục mới nhất vào cuối của tập tin? – MAK

+0

@Nick, @MAK, Không chỉ là không có gì trong Python có thể xử lý này, không có gì trong thư viện C bên dưới hoặc hệ thống tập tin. Điều này đơn giản không phải là cách các tệp hoạt động và bạn không thể phát triển tệp khác ngoài việc thêm vào trừ khi bạn sẵn sàng sao chép nội dung xung quanh. Nó có thể được thực hiện với một tập tin mới, hoặc bằng cách di chuyển dữ liệu trong tập tin cũ, nhưng cả hai cách nó rất có thể là một ý tưởng tồi. Thay đổi tốt hơn các yêu cầu hoặc cách bạn xem vấn đề ... –

1

Một biến thể của câu trả lời kdtrv của. Phiên bản này giữ nội dung tệp hiện có và cung cấp phương thức write_lines giữ nguyên thứ tự dòng.

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', 
     ] 
    ) 
Các vấn đề liên quan