2017-06-29 12 views
0

ファイルを読み込んで処理しようとしています。これはPython2.7ではうまくいきましたが、Python 3ではうまく動作しませんでした。 Python 2.7では、Python 3ではエンコーディングなしで動作しますが、Python 3ではすべての組み合わせをエンコーディングなしで試しました。バイトをPython 3.6の文字列に変換します。

ディープダイビング後、readで返されるコンテンツが両方のバージョンで異なることがわかりました。

作品はPython 2.7でのコード:

>>> f = open('resource.cgn', 'r') 
>>> content = f.read() 
>>> type(content) 
<type 'str'> 
>>> content[0:20] 
'\x04#lwq \x7f`g \xa0\x03\xa3,ess to' 
>>> content[0] 
'\x04' 

をしかし、Pythonの3で:

>>> f = open('resource.cgn','r') 
>>> content = f.read() 
Traceback (most recent call last): 
    File "<console>", line 1, in <module> 
    File "/usr/local/lib/python3.6/encodings/ascii.py", line 26, in decode 
    return codecs.ascii_decode(input, self.errors)[0] 
    UnicodeDecodeError: 'ascii' codec cant decode byte 0xa0 in position 10: ordinal not in range(128) 
>>> f = open('resource.cgn','rb') 
>>> content = f.read() 
>>> type(content)     
<class 'bytes'> 
>>> content[0:20] 
b'\x04#lwq \x7f`g \xa0\x03\xa3,ess to' 
>>> content[0] 
4 
>>> content.decode('utf8') 
Traceback (most recent call last): 
    File "<console>", line 1, in <module> 
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xa0 in position 10: 
invalid start byte 

私は、Python 2.7と同じ出力を取得したいと思います。 contentはタイプstringcontent[0]のものでなければならない'\x04'をstrが、私はこれを取得する方法について4

任意のポインタをint型ではないことでしょうか?私は何の成功もなしにエンコードを試みました。

+3

あなたが '' content.decode( 'unicode_escape')を試したことがありますか? –

+0

'content [:1]'はどうですか?それはあなたに 'b '\ x04'を与える​​でしょう。 –

+0

@SamChatsの解決策は私のために働きます。 – nCessity

答えて

0

3.Xのstrはデフォルトで2.Xのunicodeになり、3.Xのテキストモードで開いたファイルオブジェクトは、それぞれファイルの読み書き時にデコードとエンコードを試みます。 2.Xのstrは、3.Xのbytesになりました。 3.X bytesと2.Xのstrの間には、基本的に8ビットのテキストを保持する小さな違いがあります。

はここ3.Xでstrb'\x04#lwq \x7f`g \xa0\x03\xa3,ess to'を変換するための簡単なトリックです:

>>> content = ''.join(chr(x) for x in b'\x04#lwq \x7f`g \xa0\x03\xa3,ess to') 
>>> content 
'\x04#lwq \x7f`g \xa0\x03£,ess to' 
>>> content[0] 
'\x04 

bytes文字列をデコードあなたはASCIIで同じ無効なUTF-8文字のバイトを、持っているので失敗します。

ただし、bytesはバイナリデータを処理することを意味し、strは3.XのみのUnicode文字列を意味します。 3.Xでのバイナリ文字列のための代わりstrbytesを使用し、その後お勧めします:

>>> content = b'\x04#lwq \x7f`g \xa0\x03\xa3,ess to' 
>>> hex(content[0]) 
'0x4' 
+0

これは動作します。エンコードを提供せずに 'str'からバイトに戻す方法はありますか? –

+1

@HusainBasrawalaエンコーディングを提供せずに 'str'から' bytes'に変換するには: 'bytes(ord(x)for contentに')そしてそれはかなりです:-) – direprobs

+0

@HusainBasrawala: (前のコメントのコードは '.encode( 'latin1')'と似た独自のスキームを発明しようとしています)。バイトからユニコードに、またはユニコードからバイトに変換する場合、エンコーディングを提供する必要があります。[そのようなものはプレーンテキストではありません。](https://www.joelonsoftware.com/2003/10/08 /絶対最小 - ソフトウェア開発者 - 絶対に正に必要な - ユニコードとキャラクタセット - ノー - 口実 -/ – jfs

関連する問題