На этом шаге мы рассмотрим особенности чтения и записи файлов.
Вам нужно прочитать или записать текстовые данные, представленные, возможно, в различных кодировках, таких как ASCII, UTF-8 или UTF-16.
Используйте функцию open() в режиме rt для чтения текстового файла. Например:
# Прочесть остаток файла в одну строку with open('somefile.txt', 'rt') as f: data = f.read() # Итерируем по строкам файла with open('somefile.txt', 'rt') as f: for line in f: # process line
Похожим образом для записи в текстовый файл используйте open() в режиме wt (стирает и перезаписывает любое предыдущее содержание файла, если оно было):
# Пишем кусочки текстовых данных with open('somefile.txt', 'wt') as f: f.write(textl) f.write(text2) . . . . # Перенаправленная инструкция print with open('somefile.txt', 'wt') as f: print(line1, file=f) print(line2, file=f) . . . .
Чтобы добавить записываемый текст к концу существующего файла, используйте open() в режиме at.
По умолчанию файлы читаются и записываются в дефолтной системной кодировке, информацию о которой можно получить из sys.getdefaultencoding(). На большинстве компьютеров это будет utf-8. Если вы знаете, что текст, который вы читаете или пишете, представлен в другой кодировке, передайте необязательный параметр encoding функции open(). Например:
with open('somefile.txt', 'rt', encoding='latin-1') as f: . . . .
Python понимает несколько сотен текстовых кодировок. Однако самые распространенные - ascii, latin-1, utf-8 и utf-16. UTF-8 обычно является
безопасным выбором для работы с веб-приложениями. ascii соответствует 7-битным символам в диапазоне от U+0000 до U+007F.
latin-1 - это прямое отображение байтов 0-255 на символы Unicode от U-0000 до U-00FF. latin-1 известна тем, что она
никогда не вызовет ошибку декодирования при чтении текста в потенциально неизвестной кодировке. Чтение файла как latin-1 может не привести к
получению полностью правильно декодированного текста, но этого бывает достаточно для извлечения полезных данных. Также если вы позже запишете
данные обратно, первоначальные данные будут сохранены.
Чтение и запись файлов в большинстве случаев совершенно бесхитростны. Однако есть и тонкости. Во-первых, использование инструкции with в примере устанавливает контекст, в котором будут использованы файлы. Когда поток управления покидает блок with, файл будет автоматически закрыт. Вы не обязаны использовать инструкцию with, но если вы ее не применяете, то не забудьте закрыть файл:
f = open('somefile.txt', 'rt') data = f.read() f.close()
Еще одна небольшая сложность касается распознавания новых строк, символы которых отличаются в Unix и Windows (\n и \r\n). По умолчанию Python работает в так называемом "универсальном режиме новых строк". В этом режиме все распространенные символы новой строки распознаются, и все они конвертируются в единственный \n при чтении. Похожим образом символ новой строки \n конвертируется в дефолтный системный символ при выводе. Если вы не хотите использовать такую трансляцию, передайте функции open() аргумент newline=": # Читаем с отключенной трансляцией новой строки
with open('somefile.txt', 'rt', newline='') as f: . . . .
Чтобы продемонстрировать разницу, покажем, что вы увидите на компьютере с Unix, если вы читаете содержание файла в Windows-кодировке, в котором присутствуют сырые данные hello world.\r\n:
>>> # Трансляция новой строки включена (по умолчанию) >>> f = open('hello.txt', 'rt') >>> f.read() 'hello world!\n' >>> # Трансляция новой строки отключена >>> g = open('hello.txt', 'rt', newline='') >>> g.read() 'hello world!\r\n' >>>
Последняя проблема касается возможных ошибок кодировки в текстовых файлах. При чтении или записи текстового файла вы можете натолкнуться на ошибку кодирования или декодирования. Например:
>>> f = open('sample.txt', 'rt', encoding='ascii') >>> f.read() Traceback (most recent call last): . . . . UnicodeDecodeError: 'asci' codec can't decode byte 0xc3 in position 12: ordinal not in range(128) >>>
Если вы получили эту ошибку, это обычно означает, что вы не используете правильную кодировку для чтения файла. Вы должны внимательно прочитать спецификацию того, что вы пытаетесь прочесть, и удостовериться, что вы делаете это правильно (то есть не читаете данные как UTF-8 вместо Latin-1 и т. п.). Если ошибки кодирования все еще возникают, вы можете передать необязательный аргумент errors функции open(), чтобы обрабатывать ошибки. Вот несколько примеров типичных схем обработки ошибок:
>>> # Заменяем плохие символы символом замены Unicode U+fffd >>> f = open('sample.txt', 'rt', encoding='ascii', errors='replace') >>> f.read() 'Spicy Jalape?o!' >>> # Полностью игнорируем плохие символы >>> g = open('sample.txt', 'rt', encoding='ascii', errors='ignore') >>> g.read() 'Spicy Jalapeo!' >>>
Если вы постоянно мучаетесь с кодировками, аргументом errors функции open() и изобретаете хаки, вы, вероятно, зря усложняете себе жизнь. Первое правило работы с текстом: убедитесь, что вы используете правильную кодировку. А если сомневаетесь, какую выбрать, используйте системную установку по умолчанию (обычно это UTF-8).
На следующем шаге мы рассмотрим перенаправление вывода в файл.