2012-01-24 40 views
10

Đôi khi khi sử dụng ipython, bạn có thể nhấn một ngoại lệ trong một hàm đã mở tệp ở chế độ ghi. Điều này có nghĩa rằng thời gian tiếp theo bạn chạy các chức năng bạn nhận được một lỗi giá trị,Đóng tất cả các tệp đang mở trong ipython

ValueError: The file 'filename' is already opened. Please close it before reopening in write mode.

Tuy nhiên kể từ khi chức năng nghe trộm ra ngoài, tay cầm tập tin (được tạo ra bên trong hàm) bị mất, vì vậy nó không thể là đã đóng cửa. Cách duy nhất tròn nó có vẻ là để đóng phiên ipython, lúc này bạn nhận được thông báo:

Closing remaining open files: filename... done

Có cách nào để hướng dẫn ipython để đóng tập tin mà không bỏ phiên?

+5

Bạn nên cố gắng luôn sử dụng câu lệnh [ 'with'] (http://docs.python.org/reference/compound_stmts.html#the-with-statement) khi làm việc với các tập tin , ví dụ, sử dụng 'với mở (" x.txt ") như fh: '. Điều này đảm bảo rằng nếu xảy ra sự cố, tệp sẽ được đóng. – Chris

+1

@Chris bạn nên đăng câu trả lời vì đó là giải pháp hợp lệ và đơn giản duy nhất – JBernardo

+0

@JBernardo Cảm ơn bạn đã thực hiện đề xuất. – Chris

Trả lời

8

Bạn nên cố gắng luôn sử dụng câu lệnh with khi làm việc với các tệp. Ví dụ, sử dụng một cái gì đó giống như

with open("x.txt") as fh: 
    ...do something with the file handle fh 

Điều này đảm bảo rằng nếu họ gặp khó khăn trong quá trình thực của khối with, và một ngoại lệ được nâng lên, các tập tin được đảm bảo để được đóng lại. Xem with documentation để biết thêm thông tin về điều này.

Chỉnh sửa: Sau khi thảo luận trong các nhận xét, có vẻ như OP cần mở một số tệp cùng một lúc và cần sử dụng dữ liệu từ nhiều tệp cùng một lúc. Rõ ràng có rất nhiều câu lệnh lồng nhau with, một cho mỗi tệp được mở, không phải là một tùy chọn và đi ngược lại lý tưởng rằng "căn hộ tốt hơn lồng nhau".

Một tùy chọn sẽ là bọc phép tính trong khối try/finally. Ví dụ

file_handles = [] 
try: 
    for file in file_list: 
     file_handles.append(open(file)) 

    # Do some calculations with open files 

finally: 
    for fh in file_handles: 
     fh.close() 

Các khối finally chứa mã cần được chạy sau khi bất kỳ try, except hoặc else khối, ngay cả khi một ngoại lệ xảy ra. Từ documentation:

If finally is present, it specifies a "cleanup" handler. The try clause is executed, including any except and else clauses. If an exception occurs in any of the clauses and is not handled, the exception is temporarily saved. The finally clause is executed. If there is a saved exception, it is re-raised at the end of the finally clause. If the finally clause raises another exception or executes a return or break statement, the saved exception is lost. The exception information is not available to the program during execution of the finally clause.

+0

Ok nhưng sự cố tôi gặp phải với phương pháp này là tôi đang mở một vài tệp trong một vòng lặp, ví dụ:'cho fname trong fname_list: file_list.append (open (fname))' vì sau này tôi phải thực hiện các thao tác trong danh sách. Nếu tôi sử dụng cách tiếp cận 'với ...' thì tất cả các tệp được đóng trong vòng lặp - nghĩa là tôi không thể mở nhiều tệp. – tdc

+0

Bạn có cần mở đồng thời nhiều tệp không? Nếu không, sau đó chỉ cần sử dụng 'cho fname trong fname_list: với mở (fname) như fh: '. Một phần của vấn đề ban đầu của bạn là bạn đã mở các tệp và sau đó không có cách nào để đóng chúng, chúng tôi đã gặp sự cố - chỉ an toàn hơn là mở từng tệp một. – Chris

+0

Tôi cần phải có nhiều tệp mở vì tôi có nhiều bộ dữ liệu trong HDF5 và tôi đang sử dụng các pytables để truy cập chúng. Để sử dụng pytables các tập tin cần phải ở lại mở – tdc

7

Một vài ý tưởng:

  • sử dụng luôn finally (hoặc một khối with) khi làm việc với các tập tin, vì vậy họ đang đóng đúng cách.
  • bạn có thể đóng một cách mù quáng các mô tả tệp không chuẩn bằng cách sử dụng trong đó n là số lớn hơn 2 (điều này là không rõ ràng, vì vậy bạn có thể muốn xem số /proc/ipython_pid/fd/ để xem mô tả quy trình đã mở cho đến thời điểm này).
  • bạn có thể kiểm tra việc chồng bị bắt khung người dân địa phương để xem nếu bạn có thể tìm thấy những tham chiếu đến tập tin bướng bỉnh và đóng nó ... hãy xem để sys.last_traceback
Các vấn đề liên quan