2011-01-06 39 views
420

Tôi muốn thay đổi một vài tệp cùng một lúc, iff Tôi có thể viết thư cho tất cả chúng. Tôi đang tự hỏi nếu tôi bằng cách nào đó có thể kết hợp nhiều cuộc gọi mở với báo cáo kết quả with:Làm cách nào để mở nhiều tệp bằng cách sử dụng "có mở" bằng Python?

try: 
    with open('a', 'w') as a and open('b', 'w') as b: 
    do_something() 
except IOError as e: 
    print 'Operation failed: %s' % e.strerror 

Nếu đó là không thể, điều gì sẽ là một giải pháp thanh lịch cho vấn đề này như thế nào?

Trả lời

652

Tính đến Python 2.7 (hoặc 3.1 tương ứng), bạn có thể viết

with open('a', 'w') as a, open('b', 'w') as b: 
    do_something() 

Trong các phiên bản trước đó của Python, đôi khi bạn có thể sử dụng contextlib.nested() để quản lý bối cảnh tổ. Tuy nhiên, điều này sẽ không hoạt động như mong đợi khi mở các tệp bội số - xem tài liệu được liên kết để biết chi tiết.

+0

Có .. vì vậy mát mẻ rằng một vài dòng mã cho phép làm điều đó trong các phiên bản python trước là tốt, như trong ví dụ này ở đây: http://metapython.blogspot.com/2010/12/multiple-contests-in-with-statement-not.html – jsbueno

+3

Thật không may, theo các tài liệu contextlib.nested, bạn không nên sử dụng nó để mở tệp: "sử dụng lồng nhau() để mở hai tệp là lỗi lập trình vì tệp đầu tiên sẽ không bị đóng ngay nếu ngoại lệ được ném khi mở tệp thứ hai". – weronika

+17

có cách nào để sử dụng 'with' để mở danh sách các tệp không? – monkut

77

Chỉ cần thay thế and với , và bạn đã hoàn tất:

try: 
    with open('a', 'w') as a, open('b', 'w') as b: 
     do_something() 
except IOError as e: 
    print 'Operation failed: %s' % e.strerror 
+0

Bạn nên xác định phiên bản nào của Python hỗ trợ cú pháp này. –

31

Đối với việc mở nhiều file cùng một lúc hoặc các đường dẫn tập tin dài, nó có thể hữu ích để phá vỡ mọi thứ lên trên nhiều dòng. Từ Python Style Guide theo đề nghị của @Sven Marnach trong ý kiến ​​cho câu trả lời khác:

with open('/path/to/InFile.ext', 'r') as file_1, \ 
    open('/path/to/OutFile.ext', 'w') as file_2: 
    file_2.write(file_1.read()) 
2

lồng nhau với tuyên bố sẽ thực hiện công việc tương tự, và theo ý kiến ​​của tôi, là đơn giản hơn để đối phó với.

Giả sử bạn có inFile.txt và muốn viết nó thành hai outFile cùng một lúc.

with open("inFile.txt", 'r') as fr: 
    with open("outFile1.txt", 'w') as fw1: 
     with open("outFile2.txt", 'w') as fw2: 
      for line in fr.readlines(): 
       fw1.writelines(line) 
       fw2.writelines(line) 

EDIT:

Tôi không hiểu được lý do của downvote. Tôi đã thử nghiệm mã của tôi trước khi xuất bản câu trả lời của tôi, và nó hoạt động như mong muốn: Nó viết cho tất cả các outFile, giống như câu hỏi đã hỏi. Không có văn bản trùng lặp hoặc không viết. Vì vậy, tôi thực sự tò mò muốn biết tại sao câu trả lời của tôi được coi là sai, không tối ưu hoặc bất cứ điều gì như thế.

+1

Tôi không biết những gì người khác đã downvoted bạn, nhưng tôi UPVOTED bạn bởi vì đây là ví dụ duy nhất có ba tập tin (một đầu vào, hai đầu ra) đã xảy ra được chỉ là những gì tôi cần. –

+0

Cảm ơn @AdamWood! Rất vui khi biết rằng tôi có thể giúp. Chúc mừng ngày lễ! – FatihAkici

0

Với python 2,6 Nó sẽ không làm việc, chúng ta phải sử dụng dưới đây cách mở nhiều file:

with open('a', 'w') as a: 
    with open('b', 'w') as b: 
Các vấn đề liên quan