108

Python 2.7 を使用していて、どちらも Unicode 文字列を保持できるように見えるため、 のunicode代わりに型を使用することに実際にどのような利点があるのか​​疑問に思っています。エスケープ char を使用して文字列strに Unicode コードを設定できること以外に特別な理由はありますか?:unicode\

以下を使用してモジュールを実行します。

# -*- coding: utf-8 -*-

a = 'á'
ua = u'á'
print a, ua

結果: á, á

編集:

Python シェルを使用したその他のテスト:

>>> a = 'á'
>>> a
'\xc3\xa1'
>>> ua = u'á'
>>> ua
u'\xe1'
>>> ua.encode('utf8')
'\xc3\xa1'
>>> ua.encode('latin1')
'\xe1'
>>> ua
u'\xe1'

したがって、文字列は代わりに をunicode使用してエンコードされているようで、生の文字列は?を使用してエンコードされています。私は今さらに混乱しています!:Slatin1utf-8utf-8

4

4 に答える 4

184

unicodeテキストを処理するためのものです。テキストは、1 バイトよりも大きいコード ポイントのシーケンスです。テキストを特定のエンコーディングでエンコードして、テキストを生のバイトとして表すことができます (例: ... )。utf-8latin-1

unicode エンコードされていないことに注意してください。Python で使用される内部表現は実装の詳細であり、必要なコード ポイントを表現できる限り気にする必要はありません。

strに Python 2 では、単純なバイト列です。テキストを表すものではありません。

unicodeを介して表現されるバイナリ データのシーケンスにさまざまな方法でエンコードできるテキストの一般的な表現と考えることができますstr

注: Python 3 では、unicodeは に名前が変更され、単純なバイト シーケンス用のstr新しい型があります。bytes

あなたが見ることができるいくつかの違い:

>>> len(u'à')  # a single code point
1
>>> len('à')   # by default utf-8 -> takes two bytes
2
>>> len(u'à'.encode('utf-8'))
2
>>> len(u'à'.encode('latin1'))  # in latin1 it takes one byte
1
>>> print u'à'.encode('utf-8')  # terminal encoding is utf-8
à
>>> print u'à'.encode('latin1') # it cannot understand the latin1 byte
�

strを使用すると、特定のエンコーディング表現の単一バイトを低レベルで制御unicodeできますが、使用するとコードポイントレベルでしか制御できないことに注意してください。たとえば、次のことができます。

>>> 'àèìòù'
'\xc3\xa0\xc3\xa8\xc3\xac\xc3\xb2\xc3\xb9'
>>> print 'àèìòù'.replace('\xa8', '')
à�ìòù

以前は有効な UTF-8 でしたが、現在は有効ではありません。Unicode 文字列を使用すると、結果の文字列が有効な Unicode テキストではないような方法で操作することはできません。コードポイントを削除したり、コードポイントを別のコードポイントに置き換えたりすることはできますが、内部表現をいじることはできません。

于 2013-08-03T15:32:53.653 に答える
32

あなたの端末はたまたま UTF-8 に設定されています。

印刷が機能するという事実aは偶然です。生のUTF-8バイトを端末に書き込んでいます。は、 2 バイトの 16 進値 C3 および A1 を含むa長さtwoの値であり、コードポイント U+00E1 を含むua長さoneの Unicode 値です。

この長さの違いは、Unicode 値を使用する主な理由の 1 つです。バイト文字列内のテキスト文字数を簡単に測定することはできません。バイト文字列のlen()は、エンコードされた文字数ではなく、使用されたバイト数を示します。

Unicode 値を異なる出力エンコーディングにエンコードすると、違いがわかります。

>>> a = 'á'
>>> ua = u'á'
>>> ua.encode('utf8')
'\xc3\xa1'
>>> ua.encode('latin1')
'\xe1'
>>> a
'\xc3\xa1'

Unicode 標準の最初の 256 コードポイントは Latin 1 標準と一致するため、U+00E1 コードポイントは 16 進値 E1 を持つバイトとして Latin 1 にエンコードされることに注意してください。

さらに、Python は Unicode とバイト文字列の表現で同様にエスケープ コードを使用し、印刷可能な ASCII ではない下位コード ポイントも\x..エスケープ値を使用して表現されます。これが、コード ポイントが 128 から 255 の間の Unicode 文字列が、Latin 1 エンコーディングのように見える理由です。U+00FF を超えるコードポイントを持つ Unicode 文字列がある場合は、\u....代わりに 4 桁の 16 進数値を持つ別のエスケープ シーケンスが使用されます。

Unicode とエンコーディングの違いをまだ完全には理解していないようです。続行する前に、次の記事をお読みください。

于 2013-08-03T15:16:25.257 に答える
2

a をユニコードとして定義すると、文字 a と á は等しくなります。それ以外の場合、á は 2 文字としてカウントされます。len(a) と len(au) を試してください。それに加えて、他の環境で作業する場合はエンコーディングが必要になる場合があります。たとえば、md5 を使用すると、a と ua に対して異なる値が得られます。

于 2013-08-03T15:19:22.767 に答える