Unicode та кодування - це абсолютно різні, не пов'язані між собою речі.
Unicode
Призначає числовий ідентифікатор кожному символу:
- 0x41 → A
- 0xE1 → á
- 0x414 → Д
Отже, Unicode призначає число 0x41 до A, 0xE1 до á, а 0x414 - D.
Навіть у маленької стрілки → Я використав свій номер Unicode, це 0x2192. І навіть емоджи мають свої номери Unicode, 😂 - 0x1F602.
Ви можете шукати номери Unicode всіх символів у цій таблиці . Зокрема, ви можете знайти перші три символи вище тут , стрілку тут та емоджи тут .
Ці числа, присвоєні Unicode всім символам, називаються кодовими точками .
Метою всього цього є надання засобу для однозначного звернення до кожного персонажа. Наприклад, якщо я кажу про 😂, замість того, щоб сказати "знаєте, це сміються емоджи зі сльозами" , я можу просто сказати, код коду Unicode 0x1F602 . Простіше, правда?
Зауважте, що кодові точки Unicode зазвичай відформатовані з провідним U+
, тоді шістнадцяткове числове значення додається щонайменше до 4 цифр. Отже, наведеними вище прикладами будуть U + 0041, U + 00E1, U + 0414, U + 2192, U + 1F602.
Кодові точки Unicode варіюються від U + 0000 до U + 10FFFF. Це 1,114,112 цифр. 2048 з цих номерів використовуються для сурогатів , таким чином, залишається 1112 064. Це означає, що Unicode може призначити унікальний ідентифікатор (кодова точка) 1112,064 різних символів. Ще не всі ці точки коду присвоєні символу, і Unicode розширюється постійно (наприклад, коли вводяться нові емоджи).
Важливо пам’ятати, що все, що Unicode робить - це призначити числовий ідентифікатор, який називається кодовою точкою, кожному символу для легкого та однозначного посилання.
Кодування
Зображуйте символи, щоб розбити шаблони
Ці бітові структури використовуються для представлення символів у пам'яті комп'ютера або на диску.
Існує багато різних кодувань, які охоплюють різні підмножини символів. В англомовному світі найпоширенішими кодування є такі:
Карти 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 і хочу пояснити своє кодування á, мені не потрібно говорити:
"Я кодую це з aigu (або, як ви називаєте, цей піднімаючий бар) як 11100001"
Але я можу просто сказати:
"Я кодую U + 00E1 як 11100001"
І якщо я UTF-8 , я можу сказати:
"Я, в свою чергу, кодую U + 00E1 як 11000011 10100001"
І всім однозначно зрозуміло, про який персонаж ми маємо на увазі.
Тепер до часто виникаючої плутанини
Це правда, що іноді бітова модель кодування, якщо ви інтерпретуєте її як двійкове число, є такою ж, як точка коду Unicode цього символу.
Наприклад:
- ASCII кодує а також 1100001, який можна інтерпретувати як шістнадцяткове число 0x61 і точка коди Юникода є U + 0061 .
- Latin-1 кодує á , як 11100001, який можна інтерпретувати як шістнадцяткове число 0xE1 , а код точки Юникода á є U + 00E1 .
Звичайно, це було організовано спеціально для зручності. Але ви повинні дивитися на це як на чистий збіг . Бітова модель, яка використовується для представлення символу в пам'яті, жодним чином не прив’язана до кодової точки Unicode цього символу.
Ніхто навіть не каже, що ви повинні інтерпретувати такий рядок, як 11100001, як двійкове число. Просто дивитися на нього як послідовність бітів, Latin-1 використовується для кодування символів á .
Поверніться до свого питання
Кодування, що використовується інтерпретатором Python, є UTF-8 .
Ось що відбувається у ваших прикладах:
Приклад 1
Далі кодується символ á в UTF-8. У результаті виходить бітовий рядок 11000011 10100001, який зберігається у змінній a
.
>>> a = 'á'
Коли ви дивитесь на значення a
, його вміст 11000011 10100001 форматується як шістнадцяткове число 0xC3 0xA1 і виводиться у вигляді '\xc3\xa1'
:
>>> a
'\xc3\xa1'
Приклад 2
Далі зберігається кодова точка Unicode від á, що є U + 00E1, у змінній ua
(ми не знаємо, який формат даних Python використовує внутрішньо для представлення кодової точки U + 00E1 в пам'яті, і це для нас неважливо):
>>> ua = u'á'
Коли ви дивитесь на значення ua
, Python повідомляє вам, що воно містить кодову точку U + 00E1:
>>> ua
u'\xe1'
Приклад 3
Наступне кодує кодову точку Unicode U + 00E1 (представляє символ á) з UTF-8, що призводить до бітової схеми 11000011 10100001. Знову для виведення цей бітовий малюнок представлений як шістнадцятковий номер 0xC3 0xA1:
>>> ua.encode('utf-8')
'\xc3\xa1'
Приклад 4
Наступні кодує кодову точку Unicode U + 00E1 (представляє символ á) з Latin-1, що призводить до бітової схеми 11100001. Для виведення цей бітовий візерунок представлений як шістнадцятковий номер 0xE1, який за збігом обставин такий же, як початковий кодова точка U + 00E1:
>>> ua.encode('latin1')
'\xe1'
Немає зв'язку між об'єктом Unicode ua
та кодуванням Latin-1. Те, що кодовою точкою á є U + 00E1, а кодування латинських значень á дорівнює 0xE1 (якщо інтерпретувати бітову схему кодування як двійкове число), є чистим збігом обставин.
unicode
, це просто абстракція юнікода характеру;unicode
можна перетворити наstr
деяке кодування (наприкладutf-8
).