4

私はテキストファイルを読んでいます:

f = open('data.txt')
data = f.read()

ただし、data変数の改行は LF ('\n') に正規化されますが、ファイルには CRLF ('\r\n') が含まれます。

ファイルをそのまま読み取るようにPythonに指示するにはどうすればよいですか?

4

5 に答える 5

15

Python 2.x の場合:

f = open('data.txt', 'rb')

ドキュメントが言うように:

デフォルトでは、テキスト モードを使用します。これは、'\n' 文字を書き込み時にプラットフォーム固有の表現に変換し、読み取り時に戻す場合があります。したがって、バイナリ ファイル'b'を開くときは、ファイルをバイナリ モードで開くために mode 値に追加する必要があります。これにより、移植性が向上します。(追加'b'は、バイナリ ファイルとテキスト ファイルを異なる方法で処理しないシステムでも有用であり、ドキュメントとして機能します。)

Python 3.x には、次の 3 つの代替手段があります。

f1 = open('data.txt', 'rb')

これにより、改行は変換されずに残りますが、bytes代わりにも返されます。これは、自分strで明示的decodeに Unicode にする必要があります。(もちろん、2.x バージョンでは、Unicode が必要な場合は手動でデコードする必要のあるバイトも返されましたが、2.x ではそれがstrオブジェクトであり、3.xstrでは Unicode です。)

f2 = open('data.txt', 'r', newline='')

これは を返しstr、改行を未翻訳のままにします。ただし、2.x の同等物とは異なり、readlineフレンドは'\r\n'通常の文字の後に改行が続くのではなく、改行として扱われます。通常、これは問題になりませんが、問題がある場合は覚えておいてください。

f3 = open('data.txt', 'rb', encoding=locale.getpreferredencoding(False))

これは改行を 2.x のコードとまったく同じように扱いstr、デフォルトをすべて使用した場合と同じエンコーディングを使用して返しますが、現在の 3.x では有効ではなくなりました。

ストリームから入力を読み取るときに、改行が None の場合、ユニバーサル改行モードが有効になります。入力の行は '\n'、'\r'、または '\r\n' で終わることができ、これらは呼び出し元に返される前に '\n' に変換されます。'' の場合、ユニバーサル改行モードが有効になりますが、行末は翻訳されずに呼び出し元に返されます。

明示的なエンコーディングを指定する必要がある理由f3は、ファイルをバイナリ モードで開くと、デフォルトが "decode with locale.getpreferredencoding(False)" から "do not decode, and return raw " のbytes代わりにraw に変更されることを意味するためですstr。繰り返しますが、ドキュメントから:

テキスト モードでは、エンコーディングが指定されていない場合、使用されるエンコーディングはプラットフォームに依存します。現在のロケール エンコーディングを取得するために locale.getpreferredencoding(False) が呼び出されます。(未加工のバイトの読み取りと書き込みには、バイナリ モードを使用し、エンコーディングは未指定のままにします。)

でも:

'encoding' … テキスト モードでのみ使用する必要があります。

そして、少なくとも 3.3 では、これが強制されています。バイナリモードで試してみると、ValueError: binary mode doesn't take an encoding argument.

では、2.x と 3.x の両方で動作するコードを書きたい場合は、何を使用すればよいでしょうか? を扱いたい場合はbytes、明らかfに f1 are the same. But if you want to deal instr , as appropriate for each version, the simplest answer is to write different code for each, probablyf andf2` とそれぞれ。これが頻繁に発生する場合は、いずれかのラッパー関数を作成することを検討してください。

if sys.version_info >= (3, 0):
    def crlf_open(path, mode):
        return open(path, mode, newline='')
else:
    def crlf_open(path, mode):
        return open(path, mode+'b')

マルチバージョン コードを記述する際に注意すべきもう 1 つの点は、ロケールを認識したコードを記述していない場合、locale.getpreferredencoding(False)ほとんどの場合 3.x では適切な値が返されるが、通常'US-ASCII'は 2.xでは返されるだけであるということです。を使用するlocale.getpreferredencoding(True)のは技術的には正しくありませんが、エンコーディングについて考えたくない場合は、実際に使用する可能性が高くなります。(2.x と 3.x のインタープリターで両方の方法で呼び出してみて、理由を確認するか、ドキュメントを読んでください。)

もちろん、ファイルのエンコーディングを実際に知っている場合は、とにかく推測するよりも常に優れています。

いずれの場合も、'r'は「読み取り専用」を意味します。モードを指定しない場合、デフォルトは'r'であるため、デフォルトに相当するバイナリモードは です'rb'

于 2013-01-07T19:13:30.253 に答える
5

バイナリ モードでファイルを開く必要があります。

f = open('data.txt', 'rb')
data = f.read()

( 'r'「読み取り」の場合'b'、「バイナリ」の場合)

その後、すべてがそのまま返され、何も正規化されません

于 2013-01-07T19:12:58.807 に答える
1

で「バイナリの読み取り」を要求するだけopenです:

f = open('data.txt', 'rb')
data = f.read()
于 2013-01-07T19:15:39.987 に答える
0

を使用してファイルを開きますopen('data.txt', 'rb')ドキュメントを参照してください。

于 2013-01-07T19:16:44.257 に答える