2012-04-21 24 views
38

Tôi có một vấn đề để hiểu iterating trên một tập tin, Ở đây tôi đi trên những gì tôi gõ trên người diễn giải và kết quả:lặp lại trên một tập tin sử dụng Python

>>> f = open('baby1990.html', 'rU') 
>>> for line in f.readlines(): 
>>> print(line) 

>>> ... 
>>> ... all the lines from the file appear here 
>>> ... 

Khi tôi cố gắng lặp trên cùng một mở tập tin một lần nữa tôi đã không có gì !!!!

>>> f = open('baby1990.html', 'rU') 
>>> for line in f.readlines(): 
>>> print(line) 
>>> 
>>> 

Không có đầu ra nào cả, để giải quyết vấn đề này tôi đã đóng() tệp rồi mở lại để đọc !! Đó có phải là một hành vi bình thường không?

Trả lời

61

Vâng, đó là hành vi bình thường. Về cơ bản, bạn đọc phần cuối của tệp lần đầu tiên (bạn có thể sắp xếp hình ảnh đó khi đọc băng), vì vậy bạn không thể đọc thêm nữa trừ khi bạn đặt lại, bằng cách sử dụng f.seek(0) để đặt lại vị trí khi bắt đầu các tập tin, hoặc để đóng nó và sau đó mở nó một lần nữa mà sẽ bắt đầu từ đầu của tập tin.

Nếu bạn thích, bạn có thể sử dụng cú pháp with thay vào đó sẽ tự động đóng tệp cho bạn.

ví dụ

with open('baby1990.html', 'rU') as f: 
    for line in f: 
    print line 

khi khối này được thực thi xong, các tập tin được tự động đóng lại cho bạn, vì vậy bạn có thể thực hiện khối này lặp đi lặp lại mà không dứt khoát đóng cửa các tập tin bản thân và đọc các tập tin theo cách này nhiều lần.

+0

OP muốn giúp đỡ để hiểu những gì đang xảy ra khi một đối tượng tập tin được tiêu thụ. –

+0

Tôi vừa thêm phần giải thích – Levon

+1

Không có lý do gì để đọc tệp hai lần nếu bạn đang sử dụng 'readlines()'. –

1

Tất nhiên. Đó là hành vi bình thường và lành mạnh. Thay vì đóng và mở lại, bạn có thể rewind tệp.

+0

Đây không phải là hữu ích cho người dùng là không quen với các khái niệm về một con trỏ đọc – scubbo

8

Đối tượng tệp là một bộ đệm . Khi bạn đọc từ bộ đệm, phần mà bạn đọc được tiêu thụ (vị trí đọc được dịch chuyển về phía trước). Khi bạn đọc toàn bộ tệp, vị trí đọc ở EOF, vì vậy nó không trả về gì vì không có gì để đọc.

Nếu bạn phải, đối với một số lý do, thiết lập lại vị trí đọc trên một đối tượng tập tin, bạn có thể làm:

f.seek(0) 
13

Như các đối tượng tập tin đọc tập tin, nó sử dụng một con trỏ để theo dõi các nơi nó là. Nếu bạn đọc một phần của tập tin, sau đó quay trở lại nó sau đó nó sẽ nhận nơi bạn rời đi. Nếu bạn đọc toàn bộ tệp và quay trở lại cùng một đối tượng tệp, nó sẽ giống như đọc một tệp rỗng vì con trỏ ở cuối tệp và không có gì để đọc. Bạn có thể sử dụng file.tell() để xem vị trí trong tệp con trỏ và file.seek để đặt con trỏ. Ví dụ:

>>> file = open('myfile.txt') 
>>> file.tell() 
0 
>>> file.readline() 
'one\n' 
>>> file.tell() 
4L 
>>> file.readline() 
'2\n' 
>>> file.tell() 
6L 
>>> file.seek(4) 
>>> file.readline() 
'2\n' 

Ngoài ra, bạn nên biết rằng file.readlines() đọc toàn bộ tệp và lưu trữ dưới dạng danh sách.Đó là hữu ích để biết vì bạn có thể thay thế:

for line in file.readlines(): 
    #do stuff 
file.seek(0) 
for line in file.readlines(): 
    #do more stuff 

với:

lines = file.readlines() 
for each_line in lines: 
    #do stuff 
for each_line in lines: 
    #do more stuff 

Bạn cũng có thể duyệt qua một tập tin, một dòng tại một thời điểm, mà không giữ toàn bộ tập tin trong bộ nhớ (điều này có thể rất hữu ích cho các tập tin rất lớn) bằng cách thực hiện:

for line in file: 
    #do stuff