0

私はプログラミングPythonのコード例に従っていますが、何か混乱しています.単純な文字列をファイルに書き込んで読み返すコードは次のとおりです

>>> data = 'sp\xe4m'                                 # data to your script
>>> data, len(data)                                  # 4 unicode chars, 1 nonascii
('späm', 4)
>>> data.encode('utf8'), len(data.encode('utf8'))    # bytes written to file
(b'sp\xc3\xa4m', 5)
>>> f = open('test', mode='w+', encoding='utf8')     # use text mode, encoded
>>> f.write(data)
>>> f.flush()
>>> f.seek(0); f.read(1)                             # ascii bytes work
's'
>>> f.seek(2); f.read(1)                             # as does 2-byte nonascii
'ä'
>>> data[3]                                          # but offset 3 is not 'm' !
'm'
>>> f.seek(3); f.read(1)
UnicodeDecodeError: 'utf8' codec can't decode byte 0xa4 in position 0:
unexpected code byte

データ文字列が utf8 でエンコードされている場合、なぜこの UnicodeDecodeError が発生するのでしょうか。手動の f.read() での読み取りは正常に機能しますが、seek to jump および read(1) を使用すると、このエラーが表示されます。

4

1 に答える 1

2

ファイル内を検索すると、読み取りポインタが文字ではなくバイト単位で移動します。呼び出しは、.read()代わりに文字全体を読み取ることができることを期待しています。UTF-8はASCII文字セット以外のUnicodeコードポイントに複数バイトを使用するため、マルチバイトUTF-8コードポイントの真ん中にシークして機能することを期待することはできません.read()

U + 00a4コードポイント(グリフä)は、C3とA4の2バイトにエンコードされます。これは、ファイルに5バイトがあり、16進数のC3とA4を表し、次にs。を表すことを意味します。pm

位置3をシークすることにより、ファイルヘッダーをA4バイトに移動しましたが.read()、先行するC3バイトがないと、文字をデコードするのに十分なコンテキストがないため、呼び出しは失敗します。これにより、UnicodeDecodeError;が発生します。A4バイトは、有効なUTF-8シーケンスではないため、予期しないものです。

代わりに位置4を探してください:

>>> f.seek(3); f.read(1)
'm'

さらに良いことに、UTF-8データを探し回ったり、ファイルをバイナリモードで開いて手動でデコードしたりしないでください。

于 2013-02-13T10:11:45.180 に答える