Разница между разбором текстового файла в режиме r и rb - PullRequest
51 голосов
/ 10 марта 2012

Что делает анализ текстового файла в режиме 'r' более удобным, чем анализ в режиме 'rb'?Особенно, когда рассматриваемый текстовый файл может содержать не-ASCII символы.

Ответы [ 4 ]

59 голосов
/ 10 марта 2012

Это немного зависит от того, какую версию Python вы используете. В Python 2 применяется ответ Криса Дрэппера .

В Python 3 это другая (и более последовательная) история: в текстовом режиме ('r') Python проанализирует файл в соответствии с кодировкой текста, которую вы ему дадите (или, если вы ее не дадите, зависимое от платформы значение по умолчанию), и read() даст вам str. В двоичном ('rb') режиме Python не предполагает, что файл содержит вещи, которые могут быть разумно проанализированы как символы, а read() дает вам объект bytes.

Кроме того, в Python 3 универсальные символы новой строки (перевод между '\n' и соглашения о новой строке для конкретной платформы, поэтому вам не нужно о них заботиться) доступны для файлов в текстовом режиме на any Платформа, а не только Windows.

22 голосов
/ 10 марта 2012

из документации :

В Windows добавленный к режиму «b» открывает файл в двоичном режиме, поэтому существуют также режимы, такие как «rb», «wb» и «r + b». Python в Windows делает различие между текстовыми и двоичными файлами; символы конца строки в текстовых файлах автоматически слегка изменяются при чтении или записи данных. Это закулисное изменение данных файла подходит для текстовых файлов ASCII, но оно повреждает двоичные данные, подобные этим в файлах JPEG или EXE. Будьте очень осторожны, используя двоичный режим при чтении и записи таких файлов. В Unix не помешает добавить 'b' в режим, так что вы можете использовать его независимо от платформы для всех двоичных файлов.

12 голосов
/ 01 июля 2015

Разница заключается в том, как обрабатывается конец строки (EOL).Различные операционные системы используют разные символы для обозначения EOL - \n в Unix, \r в версиях Mac до OS X, \r\n в Windows.Когда файл открывается в текстовом режиме, когда файл читается, Python заменяет специфический для ОС символ конца строки, считанный из файла, просто \n.И наоборот, т. Е. Когда вы пытаетесь записать \n в файл, открытый в текстовом режиме, он будет записывать специфический для ОС символ EOL.Вы можете узнать, какая у вас ОС EOL по умолчанию, проверив os.linesep.

Когда файл открывается в двоичном режиме, сопоставление не происходит.То, что вы читаете, это то, что вы получаете.Помните, текстовый режим является режимом по умолчанию.Поэтому, если вы работаете с нетекстовыми файлами (изображения, видео и т. Д.), Обязательно откройте файл в двоичном режиме, иначе вы в конечном итоге испортите файл, введя (или удалив) некоторые байты.

Python также имеет универсальный режим перевода строки.Когда файл открывается в этом режиме, Python отображает все символы \r, \n и \r\n на \n.

2 голосов
/ 25 июля 2017

За разъяснениями и для ответа Комментарий / вопрос Агостино (У меня недостаточно репутации, чтобы комментировать, поэтому терпите меня, заявляя это как ответ ...):

В Python 2 не происходит модификации конца строки, ни в текстовом, ни в двоичном режиме - как было сказано ранее, в Python 2 применяется ответ Криса Дрэппьера (обратите внимание, что его ссылка в настоящее время указывает на 3. x Документы на Python, но текст, цитируемый Крисом, конечно, взят из Python 2, учебник по вводу и выводу )

Так что нет, не верно, что открытие файла в режиме text с Python 2 в не-Windows делает любое изменение конца строки:

0 $ cat data.txt 
line1
line2
line3
0 $ file data.txt 
data.txt: ASCII text, with CRLF line terminators
0 $ python2.7 -c 'f = open("data.txt"); print f.readlines()'
['line1\r\n', 'line2\r\n', 'line3\r\n']
0 $ python2.7 -c 'f = open("data.txt", "r"); print f.readlines()'
['line1\r\n', 'line2\r\n', 'line3\r\n']
0 $ python2.7 -c 'f = open("data.txt", "rb"); print f.readlines()'

Однако можно открыть файл в универсальном режиме новой строки в Python 2, который точно выполняет указанный мод конца строки:

0 $ python2.7 -c 'f = open("data.txt", "rU"); print f.readlines()'
['line1\n', 'line2\n', 'line3\n']

(универсальный спецификатор режима новой строки устарел с Python 3.x)

В Python 3, с другой стороны, специфичные для платформы концы строк нормализуются до '\ n' при чтении файла в текстовом режиме, а '\ n' преобразуется в конец строки по умолчанию текущей платформы при записи в текстовый режим (помимо байтов <-> юникод <-> байтов декодирование / кодирование происходит в текстовом режиме). Например. чтение файла с DOS / Win CRLF-строкой в ​​Linux нормализует конец строки до '\ n'.

...