разделим количество символов на 4.
Если это флешка на 16 Гб, то на ней можно хранить около 4 миллиардов символов,
если разделить на 4, верно? 4 байта на символ.
Это не так уж рационально.
Возможен компромисс: есть два байта,
но придется делать выбор.
Этот может работать со всеми символами.
Этот может работать с множеством наборов символов.
Но, хотя может показаться, что UTF-32 лучше,
чем UTF-16, а UTF-8 — хуже,
в итоге оказывается, что UTF-8 — лучший.
В соответствии с UTF-8 возможны один, два, три или
четыре символа, и есть специальные метки, которые указывают, сколько именно символов использовать.
Хорошо, что UTF совпадает с ASCII.
Поэтому, если вводить только символы ASCII или
набор символов Latin I, то UTF-8 и ASCII — это буквально одно и тоже.
Тогда используйте специальный символ, не входящий в ASCII,
чтобы указать на переход от однобайтовых символов к двухабйтовым,
трехбайтовым или четырехбайтовым символам.
Это переменная длина.
Это можно определить автоматически, просматривая строку,
и хоп! Вот он, этот странный символ маркера.
Значит, это UTF-8.
А если это UTF-8, можно как бы развернуть все это и найти
все эти наборы символов и все символы в этих наборах.
:8:43 басталатын видеоны ойнатыңыз және транскриптті орындаңыз8:43
Когда все это стало ясно,
то взгляните на график, он особенно ни о чем не говорит, кроме того
что UTF-8 — популярен и становится все популярнее.
А другие способы представления данных теряют популярность.
Это 2012 год, то есть очень давно.
Популярность UTF-8 стремительно растет,
а все потому, что, как только появились эти идеи, стало ясно,
что UTF-8 —это лучший способ кодирования для обмена данными между системами.
Вот почему мы говорим об этом сейчас.
С помощью этой сети можно формировать сокеты и перемещать данные между системами.
Теперь американский компьютер может «общаться» с японским,
а для этого нужно знать, какой набор символов будет на выходе, верно?
А в результате отобразятся японские символы,
хотя я вам и не показал их, азиатские символы или другие, верно?
Поэтому UTF-8 — лучший выбор
для передачи файлов между системами
или для перемещения сетевых данных между системами.
Весть мир рекомендует UTF-8, договорились?
Представьте свой компьютер, то, что внутри,
строки внутри вашего Python-кода, например, x равно hello world.
Нам все равно, какой там синтаксис.
Если файл, обычно файл Python, работающий на компьютере,
и файл используют один набор символов. В коде Python используется UTF-8.
Скорее всего, там UTF-8, но нам все равно.
Файл открывается,
поэтому при открытии файлов можно и не вспоминать об этом.
Хотя однажды можно обнаружить файл
с набором символов, отличным от привычного, но это редкий случай.
Итак, файлы внутри компьютера,
строки внутри компьютера,
но сетевые подключения не внутри, и, если мы имеем дело с базами данных,
мы видим, что они тоже не внутри компьютера.
Именно в этой части Python 3 изменился по сравнению с Python 2.
Это были очень важное обновление.
Многие считают, что это здорово, и я тоже так думаю.
Некоторые недовольны.
Думаю, это те, кто просто боится перемен.
Итак, в Python было два типа строк:
обычная строка и строка в формате Unicode.
Видите, в Python 2 можно было создать константу типа str,
вот этот тип string. Чтобы получить формат Unicode, надо добавить префикс u перед фразой.
Это особый момент, т. к. надо выполнить преобразование
между форматом Unicode и строками.
А в Python 3 —это обычная строка,
а эта —в формате Unicode, вы видите, что обе являются строками.
Поэтому, если мы что-то вставляем в среду Python,
это, возможно, приходится преобразовывать.
Но внутри языка Python все представлено в формате Unicode.
Можно ни о чем не беспокоиться.
Строки похожи друга на друга, неважно содержат ли они азиатские символы,
или символы латиницы, или испанские, или французские. Все будет в порядке.
Это упрощает наши задачи,
но есть кое-что, о чем придется побеспокоиться.
:11:29 басталатын видеоны ойнатыңыз және транскриптті орындаңыз11:29
Речь об одном типе строки, который мы еще не использовали,
но он очень важен и присутствует как Python 2, так и в Python 3.
Помните, я говорил, что когда-то символ и строка полностью соответствовали друг другу?
И всегда существовала байтовая строка.
Она обозначалась префиксом b.
Это значит, что это строка из байтов, то есть вот этот символ.
Смотрите, это байтовая строка в Python 2,
затем посмотрите на обычную строку в Python 2: обе имеют тип str (строка).
Тип строки байтов совпадает с обычной строкой, а строка в формате Unicode отличается.
Итак, в Python 2 эти две строки одинаковы, а эти две — отличаются.
:12:12 басталатын видеоны ойнатыңыз және транскриптті орындаңыз12:12
Не очень понятно у меня получается.
Итак, байтовая и обычная строки —одинаковы.
А обычная строка и строка в формате Unicode —разные.
А в Python 3 одинаковы обычная строка
и строка в формате Unicode.
:12:31 басталатын видеоны ойнатыңыз және транскриптті орындаңыз12:31
А байтовая и обычная строка отличаются, понимаете?
Получается, что байты сырые,
незакодированные, могут быть в формате UTF-8, UTF-16 или ASCII.
Мы не знаем их кодировку.
Получается, что мы должны как-то управлять
данными, которые получаем извне.
Итак, в Python 3 все внутренние строки в формате Unicode.
Не в формате UTF-8, UTF-16 или UTF-32.
Если просто нужно открыть файл, все будет работать хорошо.
А если говорить о сетях, надо понимать,
что ключевой момент в этом — необходимость преобразовывать данные.
Надо понимать, какой набор символов приходит извне.
Вся прелесть в том, что 99 или даже 100 % всей поступающей информации
использует UTF-8, поэтому все становится довольно просто.
:13:28 басталатын видеоны ойнатыңыз және транскриптті орындаңыз13:28
Существует операция декодирования. Посмотрите на этот код.
Когда мы обращаемся к внешнему ресурсу, то мы получаем массив байтов, например сокет
передает массив байтов, то есть символов.
Но их нужно декодировать, чтобы узнать, в каком они формате: UTF-8, UTF-16 или ASCII.
У массивов байтов есть такая функция.
Здесь data.decode сообщает нам, что надо разобраться.
Хорошо, что вы можете подсказать программе, какой набор символов применен,
но по умолчанию программа предполагает, что это UTF-8 или ASCII.
Потому что ASCII и UTF-8 совместимы друг с другом снизу вверх.
Если это старые данные, скорее всего, будет формат ASCII, если данные новые,
то, вероятнее всего, формат UTF-8.
Это буквально закон убывающей доходности.
Редко можно получить что-то другое, кроме этих двух форматов,
поэтому практически никогда не требуется сообщать программе об особом формате.
Надо просто обратить внимание программы на необходимость декодировать данные.
Это может быть формат ASCII или UTF-8,
но в конечном итоге все это — строка.
Здесь всюду Unicode. Это байты.
:14:32 басталатын видеоны ойнатыңыз және транскриптті орындаңыз14:32
А это Unicode.
:14:36 басталатын видеоны ойнатыңыз және транскриптті орындаңыз14:36
То есть функция decode декодирует байты и преобразовывает их в Unicode.
:14:42 басталатын видеоны ойнатыңыз және транскриптті орындаңыз14:42
А здесь, как видите, когда мы отправляем данные,
мы превращаем их в байты.
Функция encode преобразует эту строку в байты.
Вот тут будут байты, закодированные в формате UTF-8.
Можно указать здесь формат UTF-8, но программа и так предполагает это.
А это все в формате ASCII, здесь нечего делать, тут все хорошо.
Затем мы отправляем байты из команды.
Теперь мы должны отправить данные, когда мы получаем их, мы их декодируем,
а когда отправляем, то кодируем их.
UTF-8 присутствует во внешнем мире.
А здесь у нас Unicode.
:15:21 басталатын видеоны ойнатыңыз және транскриптті орындаңыз15:21
Итак, до отправки и до получения данных, их надо кодировать
или декодировать, чтобы можно было правильно их обработать.
Можно почитать в документации про кодирование и декодирование.
Decode — это метод в классе bytes.
Он понимает кодировку, которую мы сообщаем программе.
Можно указать, что это не формат UTF-8, ASCII и UTF-8 — это одно и то же.
По умолчанию, это формат UTF-8. Вероятно, именно его вы и будете использовать.
Но верно и то, что с помощью формата UTF-8 можно закодировать строки в виде массива байтов,
а затем переслать этот массив байтов во внешнюю среду.
:15:58 басталатын видеоны ойнатыңыз және транскриптті орындаңыз15:58
Все звучит сложнее, чем есть на самом деле.
Представьте все это следующим образом.
:16:8 басталатын видеоны ойнатыңыз және транскриптті орындаңыз16:08
На выходе есть внутренняя строка.
Перед отправкой ее надо закодировать и только потом отправлять.
В ответ данные возвращаются в виде байтов.
Мы знаем, что это формат UTF-8, или он определяется автоматически,
мы декодируем данные и получаем строку.
Внутри программы в среде Python можно писать файлы,
можно передавать и принимать данные, все это работает одновременно.
Вопрос только в одном: здесь UTF-8?
Это внешняя среда.
Тут нужно понимать ситуацию в целом:
если данные передаются во внешнюю среду,
то программа обращается к сокету,
поэтому нужна достаточная информация, чтобы кодировать и
декодировать данные при передаче их вовне и получении извне.
Когда внезапно замечаешь эти процессы,
кодирования и декодирования, они воспринимаются немного странно.
Но в них есть реальный смысл.
Это как барьер между внешней и внутренней средой.
Внутри наши данные полностью консистентны, и можно смешивать строки
из разных источников, не обращая внимания на набор символов в этих строках.
Теперь давайте перепишем эту программу.
Это короткая программа, но мы сделаем ее еще короче