Unicodeとエンコーディングは完全に異なり、無関係です。
Unicode
各文字に数値IDを割り当てます。
したがって、Unicodeは0x41をAに、0xE1をáに、0x414をДに割り当てます。
小さな矢印→私が使用したものにもUnicode番号があり、0x2192です。絵文字にもUnicode番号があり、😂は0x1F602です。
この表のすべての文字のUnicode番号を検索できます。特に、あなたは上記の最初の3つの文字を見つけることができ、ここに、矢印ここでは、絵文字ここに。
Unicodeによってすべての文字に割り当てられるこれらの番号は、コードポイントと呼ばれます。
これらすべての目的は、各文字を明確に参照する手段を提供することです。たとえば、私がaboutについて話している場合、「ご存知のように、涙を浮かべて笑うこの絵文字」ではなく、Unicodeコードポイント0x1F602と言えます。より簡単ですよね?
Unicodeコードポイントは通常、先頭U+
にを付けてフォーマットされ、次に16進数の数値が少なくとも4桁に埋め込まれます。したがって、上記の例はU + 0041、U + 00E1、U + 0414、U + 2192、U + 1F602になります。
Unicodeコードポイントの範囲はU + 0000からU + 10FFFFです。それは1,114,112個の数字です。これらの数のうち2048はサロゲートに使用されるため、1,112,064が残ります。つまり、Unicodeは1,112,064の異なる文字に一意のID(コードポイント)を割り当てることができます。これらのコードポイントのすべてがまだ文字に割り当てられているわけではなく、Unicodeは継続的に拡張されます(たとえば、新しい絵文字が導入されたとき)。
覚えておくべき重要なことは、すべてのUnicodeが、コードポイントと呼ばれる数値IDを各文字に割り当てて、簡単で明確な参照ができることです。
エンコーディング
文字をビットパターンにマップします。
これらのビットパターンは、コンピュータメモリまたはディスク上の文字を表すために使用されます。
文字の異なるサブセットをカバーする多くの異なるエンコーディングがあります。英語圏では、最も一般的なエンコーディングは次のとおりです。
128文字(コードポイントU + 0000〜U + 007F)を長さ7のビットパターンにマップします。
例:
この表ですべてのマッピングを確認できます。
191文字(コードポイントU + 0020からU + 007EおよびU + 00A0からU + 00FF)を長さ8のビットパターンにマップします。
例:
- a→01100001(0x61)
- á→11100001(0xE1)
この表ですべてのマッピングを確認できます。
1,112,064文字(既存のすべてのUnicodeコードポイント)を長さ8、16、24、または32ビット(つまり、1、2、3、または4バイト)のビットパターンにマップします。
例:
- a→01100001(0x61)
- á→11000011 10100001(0xC3 0xA1)
- ≠→11100010 10001001 10100000(0xE2 0x89 0xA0)
- 😂→11110000 10011111 10011000 10000010(0xF0 0x9F 0x98 0x82)
UTF-8が文字をビット文字列にエンコードする方法は、ここで非常によく説明されています。
Unicodeとエンコーディング
上記の例を見ると、Unicodeがどのように役立つかが明らかになります。
たとえば、私がLatin-1であり、自分のáのエンコーディングを説明したい場合は、言う必要はありません。
「aをaiguでエンコードします(または、立ち上がりバーと呼んでいます)を11100001としてエンコードします
しかし、私はただ言うことができます:
「U + 00E1を11100001としてエンコードします
そして、私がUTF-8なら、私は言うことができます:
「次に、U + 00E1を11000011 10100001としてエンコードします。
そして、私たちがどのキャラクターを意味するかは、誰にとっても明白です。
今度は頻繁に発生する混乱に
場合によっては、エンコードのビットパターンを2進数として解釈すると、この文字のUnicodeコードポイントと同じになることがあります。
例えば:
- ASCIIはaを1100001としてエンコードします。これは16進数0x61として解釈でき、aの UnicodeコードポイントはU + 0061です。
- Latin-1はáを11100001としてエンコードします。これは16進数0xE1として解釈でき、áの UnicodeコードポイントはU + 00E1です。
もちろん、これは便宜上、このように配置されています。しかし、あなたはそれを純粋な偶然と見なすべきです。メモリ内の文字を表すために使用されるビットパターンは、この文字のUnicodeコードポイントに関連付けられていません。
11100001のようなビット文字列を2進数として解釈する必要があると言う人はいません。Latin-1が文字áをエンコードするために使用するビットのシーケンスとして見てください。
あなたの質問に戻る
Pythonインタープリターで使用されるエンコードはUTF-8です。
これがあなたの例で起こっていることです:
例1
以下は、文字áをUTF-8でエンコードします。これにより、ビット文字列11000011 10100001が生成され、変数に保存されますa
。
>>> a = 'á'
の値を見るとa
、その内容11000011 10100001は16進数0xC3 0xA1としてフォーマットされ、次のように出力され'\xc3\xa1'
ます。
>>> a
'\xc3\xa1'
例2
次のコードは、UのU + 00E1であるáのUnicodeコードポイントを変数ua
に保存します(Pythonがメモリ内のコードポイントU + 00E1を表すために内部で使用するデータ形式は不明であり、重要ではありません)。
>>> ua = u'á'
の値を見るとua
、PythonにはコードポイントU + 00E1が含まれていることが表示されます。
>>> ua
u'\xe1'
例3
次に、UnicodeコードポイントU + 00E1(文字áを表す)をUTF-8でエンコードします。これにより、ビットパターンは11000011 10100001になります。ここでも、出力の場合、このビットパターンは16進数0xC3 0xA1として表されます。
>>> ua.encode('utf-8')
'\xc3\xa1'
実施例4
次の符号化Unicodeコードポイントラテン1、出力のビットパターン11100001.の結果は、このビットパターンが進数0xE1の、のように表されるとU + 00E1(表す文字A)に一致することにより、初期と同じですコードポイントU + 00E1:
>>> ua.encode('latin1')
'\xe1'
Unicodeオブジェクトua
とLatin-1エンコーディングの間には何の関係もありません。áのコードポイントがU + 00E1であり、áのLatin-1エンコードが0xE1である(エンコードのビットパターンを2進数として解釈する場合)ことは、まったくの偶然です。
unicode
。Unicode文字の抽象化にすぎません。いくつかのエンコーディングunicode
で変換できますstr
(例:)utf-8
。