В этом видео мы с вами продолжаем знакомство с базовыми типами и сейчас мы рассмотрим такой тип как строки и байтовые строки. Начнем мы со строк. Строка в Python это неизменяемая последовательность unicod'ных символов. Давайте посмотрим на примере. Чтобы определить строку, всё что нам нужно сделать, это записать её и обрамить в двойные кавычки. Мы видем с вами на примере, мы записали строку "курс про Python на Coursera" и напечатали её на экран. Убедимся что тип, объект, который мы только что с вами создали это str, то есть строка. Опять же, мы пользуемся встроенной функцией type для этого. Иногда может получится так, что вам внутри строки может записать слова которые включают в себя двойные кавычки. В таком случае вы можете воспользоватся одинарными кавычками для того, чтобы записать строку. На примере мы видем что Python и Coursera слова - они обрамлены двойными ковычками, но благодаря тому, что строка создавалась с помощью одинарных, у нас всё успешно вывелось на экран. Также можно двойные кавычки экранировать символом обратного слэша и таким образом мы можем двойные кавычки записывать внутри строки, которая создается с помощью двойных кавычек. Вы видите на экране у нас строка создается с помощью двойных кавычек и внутри мы экранируем символы. Также в Python'е есть концепция сырых строк. Это строки, которые начинаются с английской буквы R. Посмотрите на пример. Мы можем с помощью сырых строк объявить строку и не экранировать специальные символы, которые находятся внутри этой строки. Это очень хорошо видно на примере, например директории Windows. В первом случаи мы экранируем обратные слэши обратными слэшами и это выглядит достаточно некрасиво. Во втором случае мы используем сырые строки и просто записываем наш путь на диске. Разбить длинную строку внутри вашего кода на несколько строк можно с помощью обратного слэша. Вы записываете строку, ставите обратный слэш и переносите строчку на следующую строку кода, как видно на примере. Также есть возможность записывать строки, состоящие из нескольких абзацов, какой-то текст возможно. Это делается с помощью тройных кавычек. Как объединить две строки в одну? Иногда вам требуется объединить две строки. Это делается просто с помощью оператора сложения, с помощью знака "+" и в итоге получается новая строка. Когда вы складываете много строчек, это может быть не еффективно, потому что строки неизменяемые и при сложении нескольких строк на каждое сложение создается новый объект строковый и создается новая локация памяти. Однако в самом простейшем случае вы можете просто сложить две строки и это будет решением множества практических задач. Строки можно даже умножать, потому что для них переопределен оператор умножения. Если вы умножите строчку на три, например, то получите ту же самую строчку, повторяющуюся три раза. Я сказал, что строки неизменяемы. Давайте посмотрим на это подробно. На примере на слайде мы создаем строку. Дальше мы печатаем её адрес в памяти. Адрес памяти у объекта в Python можно запросить с помощью встроеной функции id. Далее мы к строке добавляем ещё одну строчку, чтобы у нас получилась строка "Привет мир" и печатаем адрес получившегося строкового объекта. Как мы видим, эти адреса отличаются. То есть когда мы изменили нашу начальную строку, мы на самом деле создали новый строковый объект. Обратите внимание, что я говорю строковый объект. Про объектную структуру в Python мы с вами будем говорить в отдельном видео. Я по ходу наших видео, стараюсь их подчеркнуть, что всё в Python является объектом. Следующая особенность это срезы строк. Срезы строк очень удобны для того, чтобы из целой строки выделить какую-то подстроку. Синтаксис срезов лучше всего посмотреть на примере. Давайте посмотрим пример, это всё та же строка курс про Python'a на Coursera. Далее мы берем от нее срез. Срез это-- квадратные скобки и внутри три параметра, start, stop, step. То есть, начиная с какого символа мы хотим получить подстроку, до какого символа и какой шаг. На примере мы видим, что мы берем из строки срез начиная с девятого символа и до конца. Отсутствие параметров stop, step говорит как раз, что нам нужно брать срез до конца. На втором примере мы берем срез с 9 по 15 символы. Также в срезе можно использовать отрицательные значения. Если вы посмотрите на пример, где берется срез -8:. Это означает что срез начнется с восьмого символа с конца строки, дальше двоеточие и до конца строки. Мы в итоге получаем слово "Coursera" из нашей строки. Использование step. Использование шага может быть оправдано тогда, когда вам нужно получить только символы из строки с определенным шагом. Давайте посмотрим на пример. У нас есть строка, которая состоит из цифр от 0 до 9, и мы хотим получить подстроку, которая состоит из четных чисел. В данном случае step нам очень поможет и если мы возьмем срез с шагом 2, то получим то, что мы хотим. Обычно шаг используется на практике для того, чтобы инвертировать строку, то есть развернуть её в обратном направлении. Например, у нас есть строка "Москва" и мы берем срез:-1, то есть шаг = -1, то мы получаем строку развернутую. Так как Python всё есть объект, у строк есть методы. Что это значит? Если мы определим строку и присвоим её переменой, то у этой строки мы потом можем вызывать различные методы. Например на примере мы видим вызов метода сount строки, который позволяет найти количество вхождений буквы "о" в строку. Давайте посмотрим на другой метод, который называется capitalize. Этот метод позволяет сделать первую букву в строке заглавной. Ну и последнее, на что мы посмотрим, это isdigit. Isdigit позволяет проверить является ли строка, у которой мы вызвали этот метод, числом и возвращает boolean - true или false. На самом деле существует ещё масса методов у строк, которые вы можете посмотреть в документации и с которыми вы столкнетесь на практике и в том числе в рамках нашего курса. Мы ещё будем пользоватся методами строк активно. Давайте пойдем дальше и посмотрим на оператор in, который позволяет проверить наличие подстроки в строке. Например, мы можем записать вот такую вещь и проверить, что 3.14 содержится в строке, которая написана на экране. В данном случае она содержится, поэтому результат true, то есть истина. Если мы проверим наличие подстроки, которая не содержится в строке, мы получаем false. Это очень читаемо, это очень удобно и это идиоматично. Также есть оператор for...in. Выражение for...in, которое позволяет итерироватся по строке. Как мы знаем, строка это последовательность. Последовательность юникодных символов. Соответственно итерация по строке означает взятие каждого следующего элемента по очереди. Давайте посмотрим как это сделать. Если мы объявим строковый объект изначальный "привет" и дальше проитерируемся по этой строке, используя выражение for...in, то мы можем получить каждый отдельный символ этой строки - букву П, букву Р, букву И и т.д. Конвертация типов. Давайте посмотрим, что у нас можно сделать со строкой, например с классом str. Например, у нас есть вещественное число, и мы можем в runtime, в процесе работы Python применить конвертацию типов и преобразовать вещественное число в число типа str. И на примере мы это видим. Мы берем 999.01, преобразовываем в строку и проверяем, что у нас действительно получилась в результате конвертации типов строка. Если мы попробуем преобразовать не пустую строку к логическому типу, то мы получим true. Пустая строка, которая не содержит ни одного символа в себе, при конвертации к логическому типу возвращает false. Очень часто на практике может возникнуть задача форматирования строк. Что такое "форматирование"? Форматирование строк - это процесс, когда у вас есть какой-то шаблон строковый, внутрь которого вместо определенных placeholder-ов вы хотите подставить те или иные значения из ваших переменных, например. Давайте посмотрим на первый способ форматирования в Python, которых достаточно много, на самом деле. Первый способ это вот такой, как вы видите на примере, мы placeholder-ы определяем с помощью синтаксиса %s. Это означает, что вместо этого placeholder-а мы можем подставить строку. Если бы мы хотели подставить вместо него целое число, то это был бы %d. И дальше, с помощью оператора % мы можем заменить эти placeholder-ы на наши значения. На самом деле, это достаточно богатая спецификация всевозможных placeholder-ов и про все можно почитать в документации. Мы давайте посмотрим на другой чуть более удобный способ, на мой взгляд, форматирования строк - это использование метода format, который есть у строки. В данном случае placeholder-ом являются фигурные скобки. Мы пишем строку, которая включает в себя placeholder-ы, а дальше используем метод format, которому передаем значения, которые мы должны подставить вместо placeholder-ов. В данном случае нам необязательно указывать тип внутри наших placeholder-ов, Python все это разрешит сам. Другой способ, чуть более наглядный, опять же с использованием функции format, но с именованными аргументами. В данном случае, у нас внутри placeholder-а содержится имя этих placeholder-ов, а в функцию format мы передаем, соответственно, именованные аргументы по имени, совпадающему с именем placeholder-а и получаем итоговую строку. Но, пожалуй, самый удобный способ форматирования строк в Python появился в Питоне 3.6. Это так называемые f-строки. Это строки, которые начинаются с префикса английской буквы f. Посмотрите на пример - мы можем просто объявить две переменные, а затем записать f-строку, в которой внутри placeholder-ов просто написать имена этих переменных. И вместо этих placeholder-ов будут подставлены правильные значения. Также есть возможность использовать модификаторы форматирования. Модификаторы форматирования позволяют вам сказать языку, как вы хотите то или иное значение в placeholder-е подставлять, в каком виде его в итоге вывести. Опять же, проще всего посмотреть на примере. Если у нас есть число и мы хотим вывести его в итоге на экран в двоичном представлении, мы можем воспользоваться модификатором форматирования :#b. И в итоге получаем на экране число в двоичном представлении. Другой распространенный пример, когда нам нужен модификатор форматирования, это, например, деление, которое возвращает число с очень длинной десятичной частью. Например, 2/3, мы знаем, что это будет 0.(6). Если мы хотим вывести только три знака после точки, мы можем воспользоваться модификатором форматирования.3f. Опять же, модификаторов форматирования очень много и вы можете почитать про них подробно в документации. Встроенная функция input позволяет получить ввод пользователя в виде строки. Пожалуй, лучше всего это показать на интерактивном примере в консоли. Давайте мы это сейчас и сделаем. В консоли мы запустим Python 3 name = input ("введите ваше имя"). После этого нам предлагается ввести наше имя. Давайте его введем. И после того, как мы ввели имя, нажали enter, внутри переменной name содержится как раз то значение, которое мы ввели, и мы можем с ним работать. Следующее, на что мы посмотрим, это новый тип, это байтовые строки, тип bytes. Байты, как вы знаете, это минимальная единица хранения и передачи информации. Мы не можем, например, передавать по сети строки в виде юникодных символов. Нам нужно преобразовывать строки сначала в байты. То же самое, если мы хотим сохранить строку на диск, то диск работает с байтами. Нам нужно преобразовать наши юникодные символы в байты для этой операции. В Python для того, чтобы объявить байтовую строку используется литерал b. Давайте посмотрим на примере. Чтобы объявить байтовую строку мы используем литерал b и передаем в нее строчку "hallo". В данном случае мы получаем байтовую строку и она представляет собой последовательность чисел от 0 до 255. У нас получилось это сделать, потому что мы передали в литерал байтовой строки ASCII символы. То есть, символы, которые имеют свой номер в таблице ASCII от 0 до 255 и, соответственно, преобразовываются в байты очень легко. И давайте удостоверимся, что мы действительно получили байтовую строку. Проитерируемся по нашей байтовой строке. Так как она является последовательностью, то мы можем по ней итерироваться и мы это уже умеем делать, на примере строк было показано. И мы видим, что наша байтовая строка содержит числа от 0 до 255, однако, если мы попробуем преобразовать в байты нашу юникодную строку, которая, в данном случае "привет", мы получим ошибку. Как раз потому, что байты - это числа от 0 до 255, и нам нужно юникодные символы преобразовать в байты. Для этого используются кодировки. Самая известная кодировка - это UTF-8, поэтому мы сейчас на примере покажем, как обычную строку, в данном случае строку "привет", преобразовать в байты, используя кодировку UTF-8. Давайте создадим строковый объект, убедимся, что это строка. А дальше воспользуемся методом encode, который есть у строки. Encode принимает опциональным параметром кодировку, в которую мы хотим закодировать нашу строку. В данном случае UTF-8. В принципе, это кодировка по умолчанию, поэтому мы могли бы просто использовать метод encode без каких-то дополнительных аргументов. В результате мы видим, что мы получаем байтовую строку, то есть, последовательность байт. Давайте посмотрим. Python напечатал на экран байтовую строку в виде последовательности шестнадцатиричных символов. Вначале мы видим символы d0bf. Что это такое? На самом деле, это представление маленькой кириллической буквы "п" в кодировке UTF. Если мы посмотрим в шестнадцатиричном представлении как выглядит буква "п" в кодировке UTF, мы как раз видим эти шестнадцатиричные символы d0bf. То есть, ничего магического. То же самое с другими буквами. Чтобы декодировать байты обратно в строку, мы можем воспользоваться методом строки, методом decode, который есть у байтов. Вызываем метод decode и получаем обратно UTF строку. Decode может принимать параметром кодировку, которую мы будем использовать. Но, так как мы работаем в данном случае с UTF -8, это значение по умолчанию, мы просто пишем decode без каких-то аргументов. В этом видео мы научились работать со строками, посмотрели на основные операции, которые есть у нас для работы со строками, а также посмотрели на байтовые строки, на тип bytes. Вам на практике часто придется с ними сталкиваться.