回答:
Python 3(Python 2では、この違いは少し明確ではありません)と仮定すると、文字列は文字のシーケンス、つまりUnicodeコードポイントです。これらは抽象的な概念であり、ディスクに直接保存することはできません。バイト文字列は、当然のことながら、バイトのシーケンスです。ディスクに格納できるものです。それらの間のマッピングはエンコーディングです -これらはかなりたくさんあり(そして無限に多くが可能です)-異なるエンコーディングが同じバイトをマップするかもしれないので、変換を行うために特定のケースに当てはまるものを知る必要があります別の文字列に:
>>> b'\xcf\x84o\xcf\x81\xce\xbdo\xcf\x82'.decode('utf-16')
'蓏콯캁澽苏'
>>> b'\xcf\x84o\xcf\x81\xce\xbdo\xcf\x82'.decode('utf-8')
'τoρνoς'
どちらを使用するかがわかったら.decode()
、バイト文字列のメソッドを使用して、上記のように適切な文字列を取得できます。完全を期すため.encode()
に、文字列のメソッドは逆の方法になります。
>>> 'τoρνoς'.encode('utf-8')
b'\xcf\x84o\xcf\x81\xce\xbdo\xcf\x82'
コンピュータが保存できる唯一のものはバイトです。
コンピュータに何かを保存するには、まずそれをエンコードする、つまりバイトに変換する必要があります。例えば:
MP3
にWAV
、などを使用してエンコードする必要があります。PNG
JPEG
ASCII
にUTF-8
、などを使用してエンコードする必要があります。MP3
、WAV
、PNG
、JPEG
、ASCII
およびUTF-8
の例でエンコード。エンコーディングは、オーディオ、画像、テキストなどをバイト単位で表す形式です。
Pythonでは、バイト文字列は単なるバイトのシーケンスです。人間が読める形式ではありません。内部的には、すべてをコンピューターに格納する前にバイト文字列に変換する必要があります。
一方、文字列は、単に「文字列」と呼ばれることもあり、文字のシーケンスです。人間が読める形式です。文字列を直接コンピュータに保存することはできません。最初にエンコードする必要があります(バイト文字列に変換)。やなど、文字列をバイト文字列に変換できるエンコーディングは複数ASCII
ありUTF-8
ます。
'I am a string'.encode('ASCII')
上記のPythonコードは'I am a string'
、encodingを使用して文字列をエンコードしASCII
ます。上記のコードの結果はバイト文字列になります。印刷すると、Pythonはと表しb'I am a string'
ます。ただし、バイト文字列は人間が読み取れるのではなく、ASCII
印刷時にPython がバイト文字列をデコードするだけであることに注意してください。Pythonでは、バイト文字列はで表されb
、その後にバイト文字列のASCII
表現が続きます。
エンコードに使用されたエンコードがわかっている場合は、バイト文字列をデコードして文字列に戻すことができます。
b'I am a string'.decode('ASCII')
上記のコードは、元の文字列を返します'I am a string'
。
エンコードとデコードは逆の操作です。すべてをディスクに書き込む前にエンコードし、人間が読み取る前にデコードする必要があります。
注: Python 2のサポート終了が近づいているため、Python 3についての回答を詳しく説明します。
Python 3では
bytes
8ビットの符号なし値str
のシーケンスで構成され、人間の言語のテキスト文字を表すUnicodeコードポイントのシーケンスで構成されます。
>>> # bytes
>>> b = b'h\x65llo'
>>> type(b)
<class 'bytes'>
>>> list(b)
[104, 101, 108, 108, 111]
>>> print(b)
b'hello'
>>>
>>> # str
>>> s = 'nai\u0308ve'
>>> type(s)
<class 'str'>
>>> list(s)
['n', 'a', 'i', '̈', 'v', 'e']
>>> print(s)
naïve
にもかかわらずbytes
とstr
同じように動作するように見える、そのインスタンスはすなわち、相互に互換性がない、bytes
とstr
インスタンスは同様の演算子と一緒に使用することはできません>
と+
。さらに、比較bytes
とstr
インスタンスの等価性、つまりの使用は==
、False
まったく同じ文字が含まれている場合でも常に評価されることに注意してください。
>>> # concatenation
>>> b'hi' + b'bye' # this is possible
b'hibye'
>>> 'hi' + 'bye' # this is also possible
'hibye'
>>> b'hi' + 'bye' # this will fail
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can't concat str to bytes
>>> 'hi' + b'bye' # this will also fail
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only concatenate str (not "bytes") to str
>>>
>>> # comparison
>>> b'red' > b'blue' # this is possible
True
>>> 'red'> 'blue' # this is also possible
True
>>> b'red' > 'blue' # you can't compare bytes with str
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: '>' not supported between instances of 'bytes' and 'str'
>>> 'red' > b'blue' # you can't compare str with bytes
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: '>' not supported between instances of 'str' and 'bytes'
>>> b'blue' == 'red' # equality between str and bytes always evaluates to False
False
>>> b'blue' == 'blue' # equality between str and bytes always evaluates to False
False
扱う別の問題bytes
とstr
使用して返されたファイルを扱うときに存在するopen
ビルトイン機能を。一方では、バイナリデータをファイルとの間で読み書きする場合は、常に「rb」や「wb」などのバイナリモードを使用してファイルを開きます。一方、ファイルとの間でUnicodeデータを読み書きする場合は、コンピューターのデフォルトのエンコードに注意してくださいencoding
。必要に応じて、パラメーターを渡して予期しない事態を回避してください。
Python 2では
str
8ビット値unicode
のシーケンスで構成され、Unicode文字のシーケンスで構成されます。心に留めておくべきことの一つは、ということですstr
し、unicode
あればオペレーターと一緒に使用することができるstr
唯一の7ビットのASCI文字で構成されています。
ヘルパー関数を使用str
してunicode
、Python 2とPython 2、Python 3 bytes
とstr
Python 3の間で変換すると便利な場合があります。
以下からのUnicodeとは何ですか。
基本的に、コンピューターは数値を処理するだけです。彼らはそれぞれに番号を割り当てることにより、文字やその他の文字を格納します。
……
Unicodeは、プラットフォーム、プログラム、言語に関係なく、すべての文字に一意の番号を提供します。
したがって、コンピュータが文字列を表す場合、コンピュータは文字列のコンピュータに格納されている文字を一意のUnicode番号を介して検索し、これらの数字はメモリに格納されます。ただし、これらの数値は単なる10進数であるため、文字列をディスクに直接書き込んだり、一意のUnicode番号を介してネットワーク上で送信したりすることはできません。文字列は、などのバイト文字列にエンコードする必要がありますUTF-8
。UTF-8
可能なすべての文字をエンコードできる文字エンコードであり、文字をバイトとして格納します(このようになります)。エンコードされた文字列UTF-8
は、ほぼどこでもサポートされているため、どこでも使用できます。でエンコードされたテキストファイルを開くとUTF-8
他のシステムからの場合、コンピューターはそれをデコードし、固有のUnicode番号を介してその中の文字を表示します。ブラウザがUTF-8
ネットワークからエンコードされた文字列データを受信すると、データを文字列にデコードし(ブラウザがUTF-8
エンコードされていると想定)、文字列を表示します。
python3では、文字列とバイト文字列を相互に変換できます。
>>> print('中文'.encode('utf-8'))
b'\xe4\xb8\xad\xe6\x96\x87'
>>> print(b'\xe4\xb8\xad\xe6\x96\x87'.decode('utf-8'))
中文
つまり、文字列はコンピュータで読み取るために人間に表示するためのものであり、バイト文字列はディスクへの格納とデータ転送のためのものです。
Unicodeは、文字とさまざまな種類のフォーマット(小文字/大文字、改行、キャリッジリターンなど)のバイナリ表現、およびその他の "もの"(絵文字など)について合意された形式です。コンピューターは、ASCII表現(別の一連のビット)または他の表現(一連のビット)を保存するのと同じくらい、ユニコード表現(一連のビット)をメモリまたはファイルに保存することができます。 )。
以下のための通信が行われるように、通信の当事者が使用されますどのような表現に同意しなければなりません。
ユニコードは、人とコンピュータ間の通信で使用されるすべての可能な文字(およびその他の「もの」)を表現しようとするため、多くの文字(またはもの)の表現には、他の表現システムよりも多くのビット数が必要です。より限定された文字/もののセットを表すようにしてください。「単純化」し、おそらく歴史的な使用法に対応するために、Unicode表現は、ほとんどの場合、文字をファイルに格納する目的で、他の何らかの表現システム(ASCIIなど)に変換されます。
これは、Unicodeがいる場合ではないことができないファイル内の文字を格納し、またはを介してそれらを送信するために使用される任意のそれは単にことを、通信チャネルではありません。
「文字列」という用語は正確に定義されていません。「文字列」は、その一般的な用法では、文字/もののセットを指します。コンピュータでは、これらの文字は、多くの異なるビットごとの表現のいずれかに格納されます。「バイト文字列」は、8ビットを使用する表現を使用して格納された文字のセットです(8ビットはバイトと呼ばれます)。最近では、コンピューターはユニコードシステム(可変数のバイトで表される文字)を使用してメモリに文字を格納し、バイト文字列(1バイトで表される文字)は文字をファイルに格納するため、表される文字の前に変換を使用する必要がありますメモリ内のファイル内のストレージに移動されます。
単純な1文字の文字列'š'
を用意し、それをバイトのシーケンスにエンコードしてみましょう。
>>> 'š'.encode('utf-8')
b'\xc5\xa1'
この例では、バイトシーケンスをバイナリ形式で表示します。
>>> bin(int(b'\xc5\xa1'.hex(), 16))
'0b1100010110100001'
現在、情報がどのようにエンコードされているかを知らずに情報をデコードすることは一般に不可能です。utf-8
テキストエンコーディングが使用されたことがわかっている場合にのみ、utf-8をデコードするためのアルゴリズムに従って、元の文字列を取得できます。
11000101 10100001
^^^^^ ^^^^^^
00101 100001
2進数を101100001
文字列として表示し直すことができます。
>>> chr(int('101100001', 2))
'š'
Python言語にはstr
、bytes
標準の「組み込み型」が含まれています。つまり、どちらもクラスです。Pythonがこのように実装された理由を合理化しようとする価値はないと思います。
有することを言った、str
そしてbytes
互いに非常に類似しています。どちらもほとんど同じ方法を共有しています。次のメソッドはstr
クラスに固有です。
casefold
encode
format
format_map
isdecimal
isidentifier
isnumeric
isprintable
次のメソッドはbytes
クラスに固有です。
decode
fromhex
hex
str
タイプはタイプと同じbytes
です。この答えは、unicode
型(Python 3には存在しない)と型を同等に比較していますstr
。