2012-06-21 20 views
13

Tôi cố gắng để hiểu được những sự đánh đổi thương mại/sự khác nhau giữa chúng để cách mở tập tin để chế biếnxử lý tập tin line-by-line, cho-loop vs với

with open('data.txt') as inf: 
    for line in inf: 
     #etc 

line-by-line vs

for line in open('data.txt'): 
    # etc 

tôi hiểu rằng việc sử dụng with đảm bảo các tập tin được đóng lại khi "với khối" (bộ?) được thoát (hoặc một ngoại lệ là phản đối). Vì vậy, tôi đã sử dụng with kể từ khi tôi đã học về nó ở đây.

Re for -loop: Từ tìm kiếm trên mạng và SO, có vẻ như liệu tệp có bị đóng khi số trang for bị thoát là phụ thuộc thực hiện không? Và Tôi không thể tìm thấy bất kỳ điều gì về cách cấu trúc này sẽ xử lý các trường hợp ngoại lệ . Có ai biết không?

Nếu tôi nhầm lẫn về bất kỳ điều gì ở trên, tôi đánh giá cao các chỉnh sửa, nếu không có lý do nào để sử dụng cấu trúc for trên with? (Giả sử bạn có lựa chọn, nghĩa là, không bị giới hạn bởi phiên bản Python)

Trả lời

21

Vấn đề với điều này

for line in open('data.txt'): 
    # etc 

Có phải đó là bạn không giữ một tham chiếu rõ ràng để các tập tin mở, vì vậy làm thế nào để bạn đóng nó? Cách lười biếng là chờ cho người thu gom rác dọn dẹp nó, nhưng điều đó có nghĩa là các nguồn tài nguyên không được giải phóng một cách kịp thời.

Vì vậy, bạn có thể nói

inf = open('data.txt') 
for line in inf: 
    # etc 
inf.close() 

Bây giờ những gì sẽ xảy ra nếu có một ngoại lệ trong khi bạn đang ở trong vòng lặp for? Tệp sẽ không bị đóng một cách rõ ràng.

Thêm một try/finally

inf = open('data.txt') 
try: 
    for line in inf: 
     # etc 
finally: 
    inf.close() 

này là rất nhiều mã để làm điều gì đó khá đơn giản, vì vậy Python thêm with để cho phép mã này phải được viết bằng một cách dễ đọc hơn. Điều này đưa chúng tôi đến đây

with open('data.txt') as inf: 
    for line in inf: 
     #etc 

Vì vậy, đó là cách ưa thích để mở tệp. Nếu Python của bạn quá cũ đối với câu lệnh with, bạn nên sử dụng phiên bản try/finally cho mã sản xuất

2

Tuyên bố bằng chỉ được giới thiệu trong Python 2.5 - chỉ khi bạn có yêu cầu tương thích ngược đối với các phiên bản cũ hơn bạn nên sử dụng sau này.

Bit rõ ràng hơn

Các với tuyên bố đã được giới thiệu (như bạn đang nhận thức) để bao gồm các thử/trừ/cuối cùng hệ thống - mà không phải là tuyệt vời để hiểu, nhưng không sao. Trong Python (Python trong C), việc thực hiện nó sẽ đóng các tập tin mở. Các đặc điểm kỹ thuật của ngôn ngữ chính nó, không nói ... vì vậy IPython, JPython vv ... có thể chọn để giữ cho các tập tin mở, bộ nhớ mở, bất cứ điều gì, và không tài nguyên miễn phí cho đến chu kỳ GC tiếp theo (hoặc ở tất cả, nhưng CPython GC khác với giao diện .NET hoặc Java ...).

Tôi nghĩ điều duy nhất tôi nghe được là nó thêm một mức thụt đầu dòng khác.

Vì vậy, để tóm tắt: sẽ không hoạt động < 2.5, giới thiệu từ khóa 'làm' và thêm mức thụt lề.

Nếu không, bạn giữ quyền kiểm soát xử lý ngoại lệ như bình thường và khối cuối cùng đóng tài nguyên nếu có điều gì đó thoát.

Làm việc cho tôi!

+0

Điểm tốt .. Tôi nên đặt điều gì đó khi bạn có lựa chọn trong câu hỏi - nghĩa là bạn không bị giới hạn bởi phiên bản .. Tôi sẽ cập nhật câu hỏi. Vì vậy, bình chọn của bạn sẽ đi đến 'với' sau đó? – Levon

+0

Tôi nghĩ rằng thụt lề là một lợi ích vì nó chỉ định phần nằm trong một ngữ cảnh nhất định. Bạn sẽ phải thụt lề để bọc toàn bộ khối trong một lần thử ngoại trừ việc đóng tệp trong khối cuối cùng – jdi

+0

@jdl điểm tốt - nhưng hãy để cho nó được biết vấn đề thụt lề không phải là một trong tôi nêu ra - chỉ một tôi đã đề cập là có nhận thấy nó năm trước đây trên danh sách và các nhóm. –