Александр Карпинский, Uploadcare Inc.
Александр Карпинский, 2019
Это таблица (база данных) символов, где каждый символ обладает строго заданной функцией и набором свойств.
Кодировка — это способ представить строки, состоящие из символов Юникода, в виде байтов.
Актуальные кодировки: UTF-8, UTF-16 и UTF-32.
Устаревшие: UTF-7, UCS-2, UTF-24.
Количество байт, нужных для кодирования символа:
| UTF-8 | UTF-16 | UTF-32 | |
|---|---|---|---|
| ASCII (00-007F) | 1 | 2 | 4 |
| 000080-0007FF | 2 | 2 | 4 |
| 000800-00FFFF | 3 | 2 | 4 |
| 010000-10FFFF | 4 | 4 | 4 |
str в Python 3 или unicode в Python 2.
'Питон'[0]
'П'
ord('Питон'[0])
1055
'Питон' + '3'
'Питон3'
import base64
base64.b64encode('Python')
TypeError: a bytes-like object is required, not 'str'
base64.b64encode('Python'.encode('utf-8'))
b'UHl0aG9u'
'Python'.encode('utf-8')
b'Python'
ord('Питон'[0])
1055
'Питон'.encode('utf-8')
b'\xd0\x9f\xd0\xb8\xd1\x82\xd0\xbe\xd0\xbd'
base64.b64encode('Питон'.encode('utf-8'))
b'0J/QuNGC0L7QvQ=='
Все API работают только с одним типом!
str |
bytes |
|---|---|
|
.format() json шаблоны |
base64.b64encode() socket криптография |
base64.b64decode() — для упрощения
bytes.fromhex() уже без поблажекre — фабрика, тип зависит от аргументаopen() — фабрика, тип зависит от флагаОчевидные известные вещи:
uncode → str, str → bytes
import base64
base64.b64encode(u'Python')
'UHl0aG9u'
base64.b64encode(u'Питон')
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-4: ordinal not in range(128)
Кажется сложнее, но есть возможность сделать откат в любой момент. Не надо поддерживать две версии кода и мержить изменения.
Чаще всего достаточно адаптировать под Python 3.
from __future__ import unicode_literals
str(b'Python')
"b'Python'"
bytes('Питон', encoding='utf-8')
b'\xd0\x9f\xd0\xb8\xd1\x82\xd0\xbe\xd0\xbd'
.encode() и .decode()Почти всегда можно обойтись без ветвлений типа if six.PY3.
Пока нашел одно исключение:
Функция type("ClassName", …, …)
в Python 2 принимает только str,
в Python 3 принимает только str.
b"Питон"
>> b'Python'[0]
80
Строки строго в UCS-2, прописано в стандарте.
UCS-2 это почти UTF-16, но с фиксированной шириной символа.
В UCS-2 могут быть суррогатные пары.
Есть версии интерпретаторов с UCS-2 и UCS-4.
UCS-2 компактнее в два раза, но есть суррогатные пары.
Доли рынка неизвестны. Определяется в рантайме:
import sys
sys.maxunicode
1114111 (0x10FFFF)
Для приложения выглядит как UCS-4.
В зависимости от содержимого всей строки каждый символ может занимать 1, 2 или 4 байта.
Внутреннее представление полностью переведено на UTF-8.
Большая победа для большинства строк.
Ничего не сломалось!