2013-03-24 3 views
68

Чтобы прочитать некоторый текстовый файл, в C или Pascal, я всегда использую следующие отрывки, чтобы читать данные до конца файла:Что такое идеальный аналог в Python для «пока не EOF»

while not eof do begin 
    readline(a); 
    do_something; 
end; 

Таким образом, I интересно, как я могу сделать это просто и быстро в Python?

ответ

128

Loop над файлом читать строки:

with open('somefile') as openfileobject: 
    for line in openfileobject: 
     do_something() 

Файловые объекты являются Iterable и выход линии до конца файла. Использование файлового объекта в качестве итерабельного использует буфер для обеспечения чтения результатов.

Вы можете сделать то же самое с стандартным вводом (нет необходимости использовать raw_input():

import sys 

for line in sys.stdin: 
    do_something() 

Для полноты картины, двоичное чтения может быть сделано с:

from functools import partial 

with open('somefile', 'rb') as openfileobject: 
    for chunk in iter(partial(openfileobject.read, 1024), ''): 
     do_something() 

где chunk будет содержать до до 1024 байтов за один раз из файла.

+1

Спасибо, BTW, как я могу это сделать для raw_input(), а именно ввода std. –

+1

вы должны использовать 'sys.stdin', чтобы сделать это – jozefg

+1

Спасибо, часть« sys.stdin »действительно помогает мне. –

15

Идиома Python для открытия файла и чтения строки за строкой:

with open('filename') as f: 
    for line in f: 
     do_something(line) 

Файл будет автоматически закрыт в конце вышеуказанного кода (конструкция with позаботится об этом).

Наконец, стоит отметить, что line сохранит конечную новую линию. Это можно легко удалить, используя:

line = line.rstrip() 
+1

+1, также указывая на OP, что это * не * то же самое, что и очень похожее для строки в f.readlines(): ... ', обычно предлагаемое решение. – jedwards

40

Вы можете имитировать идиом C в Python.

Для чтения буфера до max_size числа байтов, вы можете сделать это:

with open(filename,'rb') as f: 
    while True: 
     buf=f.read(max_size) 
     if not buf: break 
     process(buf) 

Или, текстовый файл построчно:

# warning -- not idiomatic Python! See below... 
with open(filename,'rb') as f: 
    while True: 
     line=f.readline() 
     if not line: break 
     process(line) 

Вы должны использовать while True/break конструкцию, так как в Python есть no eof test, кроме отсутствия байтов, возвращаемых из чтения.

В C, вы можете иметь:

while ((ch != '\n') && (ch != EOF)){ 
    // read the next ch and add to a buffer 
    // .. 
} 

Однако, вы не можете иметь это в Python:

while(line=f.readline()): 
    # syntax error 

потому assignments are not allowed in expressions в Python.

Это, конечно, болееидиоматическое в Python, чтобы сделать это:

# THIS IS IDIOMATIC Python. Do this: 
with open('somefile') as f: 
    for line in f: 
     process(line) 
+0

Который делает * не * обратные линии, конечно. –

+0

@MartijnPieters: теперь он делает :-) – dawg

+3

Как программист C и Perl, ваша точка зрения, что ** [назначения не разрешены в выражениях] (http://docs.python.org/2/faq/design.html# почему-can-ti-use-an-assign-in-an-expression) ** имеет решающее значение для меня. –

3

Вы можете использовать ниже фрагмент кода, чтобы построчно читать до конца файла

line = obj.readline() 
while(line != ''): 

    # Do Something 

    line = obj.readline() 
+1

IMO, это единственный ответ, который наилучшим образом отражает то, что было задано. – gvrocha

1

Вы можете использовать следующий фрагмент кода. readlines() читает во всем файле сразу и разбивает его по строке.

line = obj.readlines() 
6

Хотя есть предложения выше для «делать это питон путем», если кто-то хочет, чтобы действительно иметь логику, основанную на EOF, то я полагаю, с помощью обработки исключений является способом сделать это -

try: 
    line = raw_input() 
    ... whatever needs to be done incase of no EOF ... 
except EOFError: 
    ... whatever needs to be done incase of EOF ... 

Пример:

$ echo test | python -c "while True: print raw_input()" 
test 
Traceback (most recent call last): 
    File "<string>", line 1, in <module> 
EOFError: EOF when reading a line 

Или нажмите Ctrl-Z в raw_input() оперативной (Windows, Ctrl-Z Linux)

+0

@TessellatingHeckler, это не то, что [документация] (https://docs.python.org/2/library/exceptions.html#exceptions.EOFError) говорит: «Поднят, когда одна из встроенных функций (вход () или raw_input()) попадает в состояние конца файла (EOF) без чтения каких-либо данных. " –

+1

@ TadhgMcDonald-Jensen Ну эй, так и будет. Как странно. Ложное требование втянуто и несправедливо снижено. – TessellatingHeckler

Смежные вопросы