Почему я не могу использовать строку для перевода строки в write (), но могу использовать ее в Writelines ()?
Идея заключается в следующем: если вы хотите написать одну строку, вы можете сделать это с помощью write()
. Если у вас есть последовательность строк, вы можете записать их все, используя writelines()
.
write(arg)
ожидает строку в качестве аргумента и записывает ее в файл. Если вы предоставите список строк, это вызовет исключение (кстати, покажите нам ошибки!).
writelines(arg)
ожидает итератор в качестве аргумента (итеративный объект может быть кортежем, списком, строкой или итератором в самом общем смысле). Ожидается, что каждый элемент, содержащийся в итераторе, будет строкой. Вы предоставили кортеж строк, поэтому все сработало.
Природа строки (строк) не имеет значения для обеих функций, т.е. они просто записывают в файл все, что вы им предоставляете. Интересно то, что writelines()
символы новой строки не добавляются сами по себе, поэтому имя метода может сбивать с толку. На самом деле он ведет себя как вызываемый воображаемый метод write_all_of_these_strings(sequence)
.
Далее следует идиоматический способ в Python записать список строк в файл, сохраняя при этом каждую строку в отдельной строке:
lines = ['line1', 'line2']
with open('filename.txt', 'w') as f:
f.write('\n'.join(lines))
Это позаботится о закрытии файла за вас. Эта конструкция '\n'.join(lines)
объединяет (соединяет) строки в списке lines
и использует символ '\ n' в качестве связующего. Это более эффективно, чем использование +
оператора.
Начиная с той же lines
последовательности, заканчивая тем же результатом, но используя writelines()
:
lines = ['line1', 'line2']
with open('filename.txt', 'w') as f:
f.writelines("%s\n" % l for l in lines)
Это использует выражение генератора и динамически создает строки, завершающиеся новой строкой. writelines()
перебирает эту последовательность строк и записывает каждый элемент.
Изменить: еще один момент, о котором вы должны знать:
write()
и readlines()
существовала до того, как writelines()
была введена. writelines()
был представлен позже как аналог readlines()
, чтобы можно было легко записать содержимое файла, которое было только что прочитано, через readlines()
:
outfile.writelines(infile.readlines())
На самом деле, это основная причина writelines
такого запутанного названия. Кроме того, сегодня мы больше не хотим использовать этот метод. readlines()
считывает весь файл в память вашего компьютера перед тем, как writelines()
начать запись данных. Во-первых, это может напрасно тратить время. Почему бы не начать записывать части данных во время чтения других частей? Но, что наиболее важно, этот подход может потреблять очень много памяти. В крайнем случае, когда размер входного файла превышает размер памяти вашего компьютера, этот подход даже не сработает. Решение этой проблемы - использовать только итераторы. Рабочий пример:
with open('inputfile') as infile:
with open('outputfile') as outfile:
for line in infile:
outfile.write(line)
Это считывает входной файл построчно. Как только одна строка прочитана, эта строка записывается в выходной файл. Схематично говоря, всегда есть только одна строка в памяти (по сравнению со всем содержимым файла, находящимся в памяти в случае подхода строк чтения / записи).
lines
не является строкой в вашем примере. Это кортеж, состоящий из шести строк.