2012-03-10 8 views
38

'r'モードでテキストファイルを解析すると、 'rb'モードで解析するよりも便利になるのはなぜですか? 特に、問題のテキストファイルにASCII以外の文字が含まれている可能性があります。 documentationからrとrbモードのテキストファイルの解析の違い

+0

テキストファイルまたはバイナリファイルを読んでいますか? –

+0

テキストファイル。しかし、何らかの理由で私はファイルをバイトストリームとして与えています。 – MxyL

答えて

44

これは、使用しているPythonのバージョンによって少し異なります。 Python 2では、Chris Drappier's answerが適用されます。

Python 3では、テキストモード('r')とは異なる(より一貫性のある)ストーリーです。与えられたテキストエンコーディングに従ってファイルを解析します。プラットフォームに依存するデフォルト)、read()strを提供します。バイナリ('rb')モードでは、Pythonはそのファイルに文字として合理的に解析できるものが含まれていると仮定せず、read()bytesオブジェクトを返します。 Pythonの3でまた

、ユニバーサル改行('\n'とプラットフォーム固有の改行規則間の翻訳あなたがそれらを気にする必要はありませんので)上の任意のプラットフォームテキストモードのファイルのために利用可能であるだけでなく、 Windows。

+0

py3の場合、テキストモードで読み込みが自動的にエンコードの種類を検出しようとしますか?エンコードを検出しなければならないのは、バイトオブジェクトでは非常に難しいことです。 – MxyL

+1

@Keikokuメタデータなしでストリームだけに基づくエンコーディングを検出することは不可能です - アスキー+パリティではなく情報のための第8ビットを使用するさまざまなエンコーディングについて考えると、それらはすべて255の有効な1バイトシーケンスを共有しますが、それらの半分(ASCII半分)だけがそれぞれ同じ文字を表します。 Pythonのデフォルトは、セッション全体のデフォルトのエンコーディングである 'sys.getdefaultencoding()'と綴られています。私のPy3のインストールでは、そのUTF - 8が、あなたはそれが常に当てに依存することはできません。 – lvc

19

Windowsでは

、 'B' モードに追加バイナリモードでファイルを開きますので、 'RB'、 'WB'、および「R + Bのようなモードもあります' Windows上のPythonでは、テキストファイルとバイナリファイルが区別されます。テキストファイルの行末の文字は、データの読み書き時に自動的に少し変更されます。ファイルデータのこのような舞台裏の変更は、ASCIIテキストファイルでは問題ありませんが、JPEGやEXEファイルのようなバイナリデータが破損します。このようなファイルを読み書きするときは、バイナリモードを使用するように十分注意してください。 Unixでは、モードに 'b'を付けることを害しません。したがって、それをすべてのバイナリファイルに対して独立して使用することができます。

+0

基本的にバイナリモードで行を読み込もうとするのは、EOL文字が\ nか\ r \ nか何か他のものであることが保証されていないので、はるかに難しいですか? – MxyL

8

違いは、行末(EOL)の処理方法にあります。異なるオペレーティングシステムでは、UNIXではEOL-\n、OS Xより前のMacバージョンでは\r、Windowsでは\r\nとマークするために、異なる文字を使用しています。ファイルがテキストモードで開かれると、ファイルが読み込まれると、ファイルから読み取られたOS固有の行末文字が、\nに置き換えられます。逆に、テキストモードで開いたファイルに\nを書き込もうとすると、OS固有のEOL文字が書き込まれます。 os.linesepをチェックすることで、OSのデフォルトのEOLを見つけることができます。

バイナリモードでファイルを開くと、マッピングは行われません。あなたが読んだのはあなたが得るものです。テキストモードがデフォルトモードであることを覚えておいてください。あなたは非テキストファイル(画像、動画など)を処理しているのであれば、あなたはバイナリモードでファイルを開くことを確認してくださいそうしないと、いくつかのバイトを導入(または削除)して、ファイルをめちゃくちゃになってしまいます。

また、Pythonにはユニバーサル改行モードがあります。このモードでファイルを開くと、Pythonは文字\r,\n\r\nをすべて\nにマッピングします。

+0

これはPython 2とPython 3の両方で当てはまりますか? – Agostino

2

明確にするためとAgostino's comment/questionに答えるために(私は私の答えとしてこれを旨とそのコメントを負担するのに十分な評判を持っていない...):

なし行末変更は、どちらもテキストで起こらないのPython 2では

Python 2でこれまで説明したようにバイナリモードではありません。Chris Drappier's answerが適用されます(現在のリンクは3を指しています。引用されたテキストがPython 2 input and output tutorialから当然であるX Pythonのドキュメントが、クリス・)

はありませんので、非Windows上のPython 2 テキストモードでファイルを開くと任意の行の末尾を行うことではありません修正:

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

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()' 

まさに行末のmodを言っ行うんPythonの2、ユニバーサル改行モードでファイルを開くことが可能です

(ユニバーサル改行モード指定子はPython 3.xののとして推奨されていません)

のPython 3には、一方で、プラットフォーム固有の行がに正規化されたのですか終了「\ n」をテキストでファイルを読み込むときテキストモード(バイト< - >ユニコード< - >バイトのデコード/テキストモードでのエンコーディング)に加えて、 '\ n'は現在のプラットフォームのデフォルトの行末に変換されます。例えば。 LinuxでDos/WinのCRLF行で終わるファイルを読むと、行末は '\ n'に正規化されます。

+0

のpython3のopen関数はモードがどのように機能するかユニバーサル改行 https://docs.python.org/3/library/functions.html#open 「改行のコントロールを(必要であれば、それはテキストのみに適用されることを制御するための改行のパラメータを持っています\ n '、' \ r '、' \ r \ n 'のいずれかを指定することができます。有効 " – Davos

関連する問題