web-dev-qa-db-ja.com

Python 3でバイトと文字列を変換する方法は?

これはPython 101型の質問ですが、文字列入力をバイトに変換するように見えるパッケージを使用しようとしたときにしばらく困惑していました。

以下に示すように、私は自分自身の答えを見つけましたが、何が起こっているのかを明らかにするのに時間がかかったので、ここで記録する価値があると感じました。それはPython 3に一般的であるように思えるので、私が遊んでいた元のパッケージについて言及していません。エラーではないようです(特定のパッケージに.tostring()メソッドがあり、それは明らかにnot文字列として理解したものを生成していました...)

私のテストプログラムは次のようになります。

import mangler                                 # spoof package

stringThing = """
<Doc>
    <Greeting>Hello World</Greeting>
    <Greeting>你好</Greeting>
</Doc>
"""

# print out the input
print('This is the string input:')
print(stringThing)

# now make the string into bytes
bytesThing = mangler.tostring(stringThing)    # pseudo-code again

# now print it out
print('\nThis is the bytes output:')
print(bytesThing)

このコードからの出力はこれを与えます:

This is the string input:

<Doc>
    <Greeting>Hello World</Greeting>
    <Greeting>你好</Greeting>
</Doc>


This is the bytes output:
b'\n<Doc>\n    <Greeting>Hello World</Greeting>\n    <Greeting>\xe4\xbd\xa0\xe5\xa5\xbd</Greeting>\n</Doc>\n'

そのため、非ASCII文字がgobbledegookに変換されることを避けるために、バイトと文字列の間で変換できるようにする必要があります。

66
Bobble

上記のコードサンプルの「マングラー」は、これと同等のことを行っていました。

bytesThing = stringThing.encode(encoding='UTF-8')

これを書く他の方法があります(特にbytes(stringThing, encoding='UTF-8')を使用しますが、上記の構文は何が起こっているのか、また文字列を回復するために何をすべきかを明らかにします:

newStringThing = bytesThing.decode(encoding='UTF-8')

これを行うと、元の文字列が復元されます。

str(bytesThing)を使用すると、UTF-8、つまりstr(bytesThing, encoding='UTF-8')を特に要求しない限り、すべてのgobbledegookをUnicodeに変換せずに転写することに注意してください。エンコードが指定されていない場合、エラーは報告されません。

99
Bobble

Python3には、bytes()と同じ形式のencode()メソッドがあります。

str1 = b'hello world'
str2 = bytes("hello world", encoding="UTF-8")
print(str1 == str2) # Returns True

私はドキュメントでこれについて何も読んでいませんでしたが、おそらく適切な場所を探していませんでした。この方法で、文字列をバイトストリームに明示的に変換し、encodeおよびdecodeを使用するよりも読みやすく、引用符の前にbを事前に付ける必要がありません。

13
NuclearPeon

これはPython 101タイプの質問です。

単純な質問ですが、答えがそれほど単純ではない質問です。


Python3では、「bytes」オブジェクトは一連のバイトを表し、「string」オブジェクトは一連のUnicodeコードポイントを表します。

「bytes」から「string」に変換し、「string」から「bytes」に戻すには、bytes.encodeおよびstring.decode関数を使用します。これらの関数は、エンコードとエラー処理ポリシーの2つのパラメーターを取ります。

悲しいことに、テキストを表現するためにバイトシーケンスが使用されるケースは非常に多くありますが、使用されているエンコーディングが必ずしも明確に定義されているわけではありません。

堅牢なソフトウェアを作成する場合は、これらのパラメーターについて慎重に検討する必要があります。バイトがどのエンコーディングにあるべきか、また、バイトが本来あるべきだと思ったエンコーディングに対して有効なバイトシーケンスではないことが判明した場合の対処方法について慎重に検討する必要があります。PythonデフォルトはUTF-8で、有効なUTF-8ではないバイトシーケンスでエラーが発生します。

print(bytesThing)

Pythonは、文字列へのフォールバック変換として「repr」を使用します。 reprは、オブジェクトを再作成するpythonコードを生成しようとします。バイトオブジェクトの場合、これはとりわけ、印刷可能なASCII範囲外のバイトをエスケープすることを意味します。

0
plugwash