автордың кітабын онлайн тегін оқу Простой Python. Современный стиль программирования
Переводчики Е. Зазноба, И. Пальти
Литературные редакторы Н. Кудрейко, Н. Хлебина
Художник В. Мостипан
Корректоры Е. Павлович, Е. Рафалюк-Бузовская
Билл Любанович
Простой Python. Современный стиль программирования. 2-е изд. . — СПб.: Питер, 2020.
ISBN 978-5-4461-1639-3
© ООО Издательство "Питер", 2020
Все права защищены. Никакая часть данной книги не может быть воспроизведена в какой бы то ни было форме без письменного разрешения владельцев авторских прав.
С любовью к Мэри, Тому и Рокси, а также Кэрин и Эрику.
Введение
Как и обещает название, книга познакомит вас с одним из самых популярных языков программирования — Python. Издание предназначено как для начинающих программистов, так и для тех, кто уже имеет опыт в написании программ и просто желает добавить Python к списку доступных ему языков.
В большинстве случаев изучать компьютерный язык проще, чем человеческий, — в нем меньше двусмысленностей и исключений, которые приходится запоминать. Python — один из самых последовательных и понятных компьютерных языков, он сочетает в себе простоту изучения, простоту использования и большую выразительную силу.
Компьютерные языки состоят из данных — аналогами в разговорной речи являются существительные — и инструкций (или кода), которые можно сравнить с глаголами. Изучить нужно будет и то и другое: вы освоите основы кода и структур данных и узнаете, как их объединить. Затем перейдете к более сложным темам, а программы, которые вы будете читать и писать, станут длиннее и сложнее. Если провести аналогию с работой по дереву, мы начнем с молотка, гвоздей и небольших кусков древесины, а во второй половине книги обратимся к более специализированным инструментам, которые можно сравнить с токарными станками и другими более сложными устройствами.
Вам нужно знать не только сам язык, но и то, что с его помощью можно делать. Мы начнем с языка Python и его стандартной библиотеки, готовой к работе прямо «из коробки». Помимо этого, я покажу вам, как находить, загружать, устанавливать и использовать качественные сторонние пакеты: касаться узких тем или рассматривать сложные трюки не буду, а сделаю акцент на том, что после десяти лет работы с Python считаю действительно полезным.
Несмотря на то что книга представляет собой введение в Python, в ней мы затронем и несколько дополнительных тем, с которыми, на мой взгляд, следует ознакомиться еще на начальном этапе. Работе с базами данных и Интернетом мы тоже уделим внимание, однако не станем забывать, что технологии меняются очень быстро — теперь от программиста на Python общество ждет знаний об облачных технологиях, машинном обучении и создании потоков событий: основную информацию по этим темам вы также здесь найдете.
Язык Python имеет некоторые специальные функции, работающие лучше, чем адаптированные стили программирования из других языков. Например, использование ключевого слова for и итераторов — более прямой способ создания цикла: пользоваться им гораздо удобнее, нежели вручную инкрементировать переменную-счетчик.
Когда вы изучаете что-то новое, бывает трудно определиться с тем, какие слова являются терминами и какие понятия на самом деле важны. Иначе говоря, тестировалась ли эта функциональность? Я выделю некоторые термины и понятия, которые имеют особое значение в Python. Код, написанный на языке Python, можно будет увидеть даже в самых первых главах.
Подобные примечания я буду делать, когда что-то может быть непонятным или же существует более питонский способ решить проблему.
Python неидеален. Я обращу ваше внимание на то, что кажется сомнительным и чего следует избегать, и предложу альтернативные варианты.
По некоторым темам, таким как наследование объектов, MVC или проектирование REST для работы с Интернетом, мое мнение может отличаться от общепринятого. Вам самим решать, к кому прислушаться.
Для кого эта книга
Эта книга для всех, кто заинтересован в изучении одного из самых популярных во всем мире языков программирования. Наличие или отсутствие опыта с другими языками программирования не имеет значения.
Что нового во втором издании
Что изменилось со времени выхода первого издания?
• Добавилось около 100 страниц, в том числе с изображением котиков.
• Количество глав удвоилось, но сами главы стали короче.
• В начале книги появилась глава, посвященная типам данных, переменным и именам.
• Рассмотрены новые особенности Python, такие как f-строки.
• Рекомендованы новые или улучшенные сторонние библиотеки.
• Во всей книге присутствуют новые примеры кода.
• Для начинающих разработчиков добавлен текст с описанием аппаратного и программного обеспечения.
• Более опытные разработчики могут ознакомиться с библиотекой asyncio.
• Рассмотрен новый стек технологий: контейнеры, облачные технологии, наука о данных и машинное обучение.
• Добавлены подсказки, с помощью которых вы сможете найти работу программиста на Python.
Что не изменилось? Примеры, в которых используются плохие стихотворения и утки. Они с нами навсегда.
Структура книги
В первой части излагаются основы языка программирования Python: главы 1–11 следует читать по порядку. Я оперирую простейшими структурами данных и кода, постепенно составляя из них более сложные и реалистичные программы. Во второй части (главы 12–22) показывается, каким образом язык программирования Python используется в определенных прикладных областях, таких как Интернет, базы данных, сети и т.д.: эти главы можно читать в любом порядке.
Вот краткое содержание всех глав и приложений и обзор новых терминов, с которыми вы там встретитесь.
•Глава 1. «Python: с чем его едят». Компьютерные программы не так уж и отличаются от других инструкций, с которыми вы сталкиваетесь каждый день. Мы рассмотрим небольшие программы, написанные на Python. Они продемонстрируют синтаксис языка, его возможности и способы применения в реальном мире. Вы узнаете, как запустить программу внутри интерактивного интерпретатора (оболочки), а также из текстового файла, сохраненного на вашем компьютере.
• Глава 2. «Данные: типы, значения, переменные и имена». В компьютерных языках используются данные и инструкции. Компьютер по-разному хранит и обрабатывает разные типы данных. Их значения или можно изменять (такие типы называются изменяемыми), или нельзя (неизменяемые типы). В программе, написанной на Python, данные могут быть представлены как литералами (числами вроде 78 или текстовыми строками вроде "waffle"), так и именованными переменными. В отличие от многих других языков программирования Python относится к переменным как к именам, и это влечет за собой некоторые важные последствия.
• Глава 3. «Числа». В этой главе показываются простейшие типы данных, применяемые в языке программирования Python: булевы переменные, целыечисла и числа с плавающей точкой. Вы также изучите простейшую математику. В примерах этой главы интерактивный интерпретатор Python используется как калькулятор.
• Глава 4. «Выбираем с помощью оператора if». С существительными (типами данных) и с глаголами (программными структурами) мы поработаем в нескольких главах. Код, написанный на Python, обычно выполняется по одной строке за раз: от начала программы до ее конца. Структура if позволяет запускать разные строки кода исходя из результата сравнения определенных данных.
• Глава 5. «Текстовые строки». Здесь мы обратимся к существительным и миру текстовых строк. Вы научитесь создавать, объединять, изменять и получать строки, а также выводить их на экран.
• Глава 6. «Создаем циклы с помощью ключевых слов while и for». Снова глаголы. Вы научитесь создавать цикл двумя способами — с помощью for и с помощью while, а также узнаете, что такое итераторы — одно из основных понятий Python.
• Глава 7. «Кортежи и списки». Пришло время рассмотреть первые структуры данных более высокого уровня: списки и кортежи. Они представляют собой последовательности значений, которыми вы будете пользоваться как конструктором Lego для того, чтобы создавать более сложные структуры. Вы научитесь проходить по ним с помощью итераторов, а также быстро создавать списки с помощью списковых включений.
• Глава 8. «Словари и множества». Словари и множества позволяют сохранять данные не по позиции, а по их значению. Вы увидите, насколько это удобно, — данная особенность Python станет одной из ваших любимых.
• Глава 9. «Функции». Соединяйте структуры данных из предыдущих глав со структурами кода, чтобы выполнять сравнение, выборку или повторение операций. Упаковывайте код в функции и обрабатывайте ошибки с помощью исключений.
• Глава 10. «Ой-ой-ой: объекты и классы». Слово «объект» недостаточно конкретно, но имеет большое значение во многих компьютерных языках, в том числе и в Python. Если вы уже занимались объектно-ориентированным программированием на других языках, то в сравнении с ними Python покажется вам более простым. В этой главе объясняется, когда следует использовать объекты и классы, а когда лучше выбрать другой путь.
• Глава 11. «Модули, пакеты и программы». Вы узнаете, как перейти к более крупным структурам кода — модулям, пакетам и программам, а также где можно разместить код и данные, как ввести и вывести данные, обработать различные параметры, просмотреть стандартную библиотеку Python и то, что находится вне ее.
• Глава 12. «Обрабатываем данные». Вы научитесь профессионально обрабатывать данные и управлять ими. Эта глава полностью посвящена текстовым и двоичным данным, особенностям использования символов стандарта Unicode, а также поиску текста с помощью регулярных выражений. Вы познакомитесь с типами данных byte и bytearray — соперниками типа string, в которых содержатся необработанные бинарные значения вместо текстовых символов.
• Глава 13. «Календари и часы». С датой и временем работать бывает непросто. Здесь мы рассмотрим распространенные проблемы и способы их решения.
• Глава 14. «Файлы и каталоги». Простые хранилища данных используют файлы и каталоги. В этой главе речь пойдет о создании и использовании файлов и каталогов.
• Глава 15. «Данные во времени: процессы и конкурентность». Это первая глава, в которой мы приступаем к изучению системы. Начнем с данных во времени — вы научитесь использовать программы, процессы и потоки для того, чтобы выполнять больше работы за один промежуток времени (конкурентность). Среди прочего будут упомянуты последние добавления в async (более подробно они рассматриваются в приложении В).
• Глава 16. «Данные в коробке: надежные хранилища». Данные могут храниться в простых файлах и каталогах внутри файловых систем и структурироваться с помощью распространенных форматов, таких как CSV, JSON и XML. Однако по мере того, как объем и сложность данных будут расти, вам, возможно, придется использовать базы данных — как традиционные реляционные, так и современные базы данных NoSQL.
• Глава 17. «Данные в пространстве: сети». Отправляйте ваш код и данные через пространство по сетям с помощью служб, протоколов и API. В качестве примеров рассматриваются как низкоуровневые сокеты, библиотеки обмена сообщениями и системы массового обслуживания, так и развертывание в облачных системах.
• Глава 18. «Распутываем Всемирную паутину». Всемирной сети посвящена отдельная глава, в которой рассматриваются клиенты, серверы, извлечение данных, API и фреймворки. Вы научитесь искать сайты и извлекать из них данные, а затем разработаете реальный сайт, используя параметры запросов и шаблоны.
• Глава 19. «Быть питонщиком». В этой главе содержатся советы для программистов, пишущих на Python: вы получите рекомендации по установке (с помощью pip и virtualenv), использованию IDE, тестированию, отладке, журналированию, контролю исходного кода и документации. Узнаете также, как найти и установить полезные пакеты сторонних разработчиков, как упаковать свой код для повторного использования и где получить более подробную информацию.
• Глава 20. «Пи-Арт». При помощи языка программирования Python можно создавать произведения искусства: в графике, музыке, анимации и играх.
• Глава 21. «За работой». У Python есть специальные приложения для бизнеса: визуализация данных (графики, графы и карты), безопасность и регулирование.
• Глава 22. «Python в науке». За последние несколько лет Python стал главным языком науки, он используется в математике, статистике, физике, биологии и медицине. Его сильные стороны — наука о данных и машинное обучение. В этой главе демонстрируются возможности таких инструментов, как NumPy, SciPy и Pandas.
• Приложение А. «Аппаратное и программное обеспечение для начинающих программистов». Если вы новичок в мире программирования, из этого приложения вы можете узнать, как на самом деле работает аппаратное и программное обеспечение и что означают некоторые термины, с которыми в дальнейшем вам придется сталкиваться.
• Приложение Б. «Установка Python 3». Если вы еще не установили Python 3 на свой компьютер, в этом приложении вы найдете информацию о том, как это сделать независимо от того, какая операционная система у вас установлена: Windows, Mac OS/X, Linux или другой вариант Unix.
• Приложение В. «Нечто совершенно иное: async». В разных релизах Python добавляется функциональность для работы с асинхронностью — разобраться с ней может быть сложно. Я упоминаю о ней в тех главах, в которых заходит речь об асинхронности, но в этом приложении рассматриваю тему более подробно.
• Приложение Г. «Ответы к упражнениям». Здесь содержатся ответы на упражнения, приведенные в конце каждой главы. Не подглядывайте туда, пока не попробуете решить задачи самостоятельно, в противном случае вы рискуете превратиться в козленочка.
•Приложение Д. «Вспомогательные таблицы». В этом приложении содержатся справочные данные.
Версии Python
Языки программирования со временем изменяются — разработчики добавляют в них новые возможности и исправляют ошибки. Примеры этой книги написаны и протестированы для версии Python 3.7. Версия 3.7 является наиболее современной на момент выхода этой книги, и о самых значимых нововведениях я расскажу. Версия 3.8 вышла в конце 2019 года — я рассмотрю самую ожидаемую функциональность1. Узнать, что и когда было добавлено в язык программирования Python, можно, посетив страницу https://docs.python.org/3/whatsnew/: там представлена техническая информация. Она, скорее всего, покажется трудной для понимания, если вы только начинаете изучать Python, но может пригодиться в будущем, если вам нужно будет писать программы для компьютеров, на которых установлены другие версии Python.
Условные обозначения
В этой книге приняты следующие шрифтовые соглашения.
Курсив
Им обозначаются новые термины и понятия.
Моноширинный шрифт
Используется в листингах программного кода, а также для имен и расширений файлов, названий путей, имен функций, команд, баз данных, переменных, операторов и ключевых слов.
Зеленый моноширинный шрифт
Указывает текст, который необходимо заменить пользовательскими значениями или значениями, определяемыми контекстом.
Так оформлены совет, предложение или замечание.
Таким образом оформлено предупреждение.
Использование примеров кода
Примеры кода и упражнения, приведенные в тексте, доступны для загрузки по адресу https://github.com/madscheme/introducing-python. Эта книга написана, чтобы помочь вам в работе: вы можете применить код, содержащийся в ней, в ваших программах и документации и не связываться с нами, чтобы спросить разрешения, если собираетесь воспользоваться небольшим фрагментом кода. Например, если вы пишете программу и кое-где вставляете в нее код из книги, никакого особого разрешения не требуется. Однако если вы запишете на диск примеры из книги и начнете раздавать или продавать такие диски, разрешение на это получить необходимо. Если вы цитируете это издание, отвечая на вопрос, или воспроизводите код из него в качестве примера, разрешения не требуется. Но если включаете значительный фрагмент кода из данной книги в документацию по вашему продукту, необходимо разрешение.
Ссылки на источник приветствуются, но не обязательны. В такие ссылки обычно включаются название книги, имя ее автора, название издательства и номер ISBN. Например: «Простой Python. Современный стиль программирования. 2-е изд. Билл Любанович. Питер, 2020. 978-5-4461-1639-3».
При любых сомнениях относительно превышения разрешенного объема использования примеров кода, приведенных в данной книге, можете обращаться к нам по адресу permissions@oreilly.com.
От издательства
Ваши замечания, предложения, вопросы отправляйте по адресу comp@piter.com (издательство «Питер», компьютерная редакция).
Мы будем рады узнать ваше мнение!
На веб-сайте издательства www.piter.com вы найдете подробную информацию о наших книгах.
1 Оригинальное издание выпущено до выхода версии 3.8. Текущая версия — 3.8.2. — Примеч. ред.
Языки программирования со временем изменяются — разработчики добавляют в них новые возможности и исправляют ошибки. Примеры этой книги написаны и протестированы для версии Python 3.7. Версия 3.7 является наиболее современной на момент выхода этой книги, и о самых значимых нововведениях я расскажу. Версия 3.8 вышла в конце 2019 года — я рассмотрю самую ожидаемую функциональность1. Узнать, что и когда было добавлено в язык программирования Python, можно, посетив страницу https://docs.python.org/3/whatsnew/: там представлена техническая информация. Она, скорее всего, покажется трудной для понимания, если вы только начинаете изучать Python, но может пригодиться в будущем, если вам нужно будет писать программы для компьютеров, на которых установлены другие версии Python.
Оригинальное издание выпущено до выхода версии 3.8. Текущая версия — 3.8.2. — Примеч. ред.
Благодарности
Искренне благодарю обозревателей и читателей, помогавших сделать эту книгу лучше: Корбина Коллинза, Чарльза Гивра, Нейтана Стокса, Дейва Джорджа и Майка Джеймса.
Об авторе
Билл Любанович программировал в операционной системе Unix с 1977 года, разрабатывал GUI с 1981 года, базы данных — с 1990 года, а веб-разработкой занимался с 1993 года. Кроме того:
• 1982–1988 (Intran) — разрабатывал приложение Metaform на первой коммерческой графической рабочей станции;
• 1990–1995 (Northwest Airlines) — написал визуальную систему управления доходами, а также первый тест для анализа онлайн-маркетинга в Сети;
• 1994 (Tela) — стал сооснователем одного из первых интернет-провайдеров;
• 1995–1999 (WAM!NET) — разрабатывал веб-доски сообщений и 3М Digital Media Repository;
• 1999–2005 (Mad Scheme) — стал сооснователем компании, занимающейся веб-разработкой и хостингом;
• 2005 (O’Reilly) — в соавторстве написал несколько глав книги Linux Server Security2;
• 2007 (O’Reilly) — в соавторстве написал книгу Linux System Administration3;
• 2010–2013 (Keep) — разработал и построил службы Core Services, соединяющие веб-фронтенды и бэкенды, работающие с базами данных;
• 2014 (O’Reilly) — написал книгу Introducing Python (первое издание)4;
• 2015–2016 (Internet Archive) — работал над API и адаптацией Wayback Machine на Python;
• 2016–2018 (CrowdStrike) — управлял сервисами на базе Python, которые обрабатывают миллиарды ежедневных событий, связанных с безопасностью.
Билл счастливо живет в горах Сангре-де-Сасквоч в штате Миннесота со своей чудесной семьей: женой Мэри, сыном Томом (и его женой Рокси) и дочерью Кэрин (и ее мужем Эриком), ухаживает за кошками Ингой и Люси и котом Честером.
• 2007 (O’Reilly) — в соавторстве написал книгу Linux System Administration3;
Bauer M. Linux Server Security, 2nd Edition. — O’Reilly, 2009.
Любанович Б. Простой Python. Современный стиль программирования. — СПб.: Питер, 2019.
Адельштайн Т., Любанович Б. Системное администрирование в Linux. — СПб.: Питер, 2010.
• 2005 (O’Reilly) — в соавторстве написал несколько глав книги Linux Server Security2;
• 2014 (O’Reilly) — написал книгу Introducing Python (первое издание)4;
Часть I. Основы Python
Глава 1. Python: с чем его едят
Популярными становятся только уродливые языки. Python — исключение из этого правила.
Дональд Кнут
Тайны
Начнем с двух небольших тайн и их разгадок. Что, по-вашему, означают следующие две строки?
(Ряд 1): (RS) K18, ssk, k1, turn work.
(Ряд 2): (WS) Sl 1 pwise, p5, p2tog, p1, turn.
Выглядит как некая компьютерная программа. На самом деле это схема для вязания — точнее, фрагмент, который описывает, как связать пятку носка. Похожие носки показаны на рис. 1.1.
Рис. 1.1. Вязаные носки
Для меня эти строки имеют не больше смысла, чем судоку для одного из моих котов, но вот моя жена совершенно точно понимает написанное. Если вы вяжете, то тоже поймете.
Рассмотрим еще один таинственный текст, который можно увидеть записанным на листочке из блокнота. Вы сразу поймете его предназначение, даже если и не догадаетесь о том, каким будет конечный продукт:
1/2 столовой ложки масла или маргарина;
1/2 столовой ложки сливок;
2 1/2 стакана муки;
1 чайная ложка соли;
1 чайная ложка сахара;
4 стакана картофельного пюре (охлажденного).
Перед тем как добавить муку, убедитесь, что все ингредиенты охлаждены.
Смешайте все ингредиенты.
Тщательно замесите.
Сделайте 20 шариков.
Держите их охлажденными до следующего этапа.
Для каждого шарика:
присыпьте разделочную доску мукой;
раскатайте шарик при помощи рифленой скалки;
жарьте на сковороде до подрумянивания;
переверните и обжарьте другую сторону.
Даже если вы не готовите, вы сможете распознать кулинарный рецепт: список продуктов, за которым следуют указания по приготовлению. Но что получится в итоге? Это лефсе, норвежский деликатес, который напоминает тортилью (рис. 1.2). Полейте блюдо маслом, вареньем или чем-либо еще, сверните и наслаждайтесь.
Рис. 1.2. Лефсе
Схема для вязания и рецепт имеют несколько схожих моментов:
• фиксированный словарь, состоящий из слов, аббревиатур и символов: какие-то могут быть вам знакомы, какие-то — нет;
• правила, описывающие, что и где можно говорить, — синтаксис;
• последовательность операций, которые должны быть выполнены в определенном порядке;
• в некоторых случаях — повторение определенных операций (цикл), например способ приготовления каждого кусочка лефсе;
• в некоторых случаях — ссылка на еще одну последовательность операций (говоря компьютерными терминами, функцию). Например, когда вы прочтете приведенный выше рецепт, вам может понадобиться рецепт приготовления картофельного пюре;
• предполагаемое знание контекста. Рецепт подразумевает ваше знание о том, что такое вода и как ее кипятить. Схема для вязания подразумевает, что вы умеете держать спицы в руках;
• кое-какие данные, которые нужно использовать, создать или изменить, — картофель и нитки;
• инструменты, которые используются для работы с данными, — горшки, миксеры, духовки, вязальные спицы;
• ожидаемый результат. В наших примерах результатом будет предмет для ног и предмет для желудка. Главное — не перепутать.
Как ни назови — идиомы, жаргон, — примеры их использования можно встретить везде. Жаргон помогает сэкономить время тем, кто его знает, а для других людей оставляет информацию совершенно непонятной. Попробуйте расшифровать колонку газеты, посвященную бриджу, если вы не играете в эту игру, или научную статью — если вы не ученый (или ученый, но в другой области).
Маленькие программы
Подобные идеи вы встретите и в компьютерных программах, которые сами по себе являются маленькими языками: через них люди говорят компьютеру, что делать. Схему для вязания и рецепт я использовал для демонстрации того, что программы не так страшны, как может показаться, — всего лишь нужно выучить верные слова и правила.
Понять этот маленький язык гораздо легче, если в нем не очень много слов и правил и если вам не нужно изучать их все одновременно: за один раз наш мозг может воспринять только ограниченное количество знаний.
Пришло время обратиться к настоящей программе (пример 1.1). Как вы думаете, что она делает?
Пример 1.1. countdown.py
for countdown in 5, 4, 3, 2, 1, "hey!":
print(countdown)
Если вы считаете, что это программа, написанная на языке программирования Python, которая выводит на экран следующее:
5
4
3
2
1
hey!
то вы знаете, что Python выучить проще, чем понять рецепт или схему для вязания. К тому же тренироваться писать на этом языке вы можете, сидя за удобным и безопасным столом и избегая опасностей вроде горячей воды и спиц.
Программа, написанная на языке программирования Python, содержит некоторое количество специальных слов и символов: for, in, print, запятые, точки с запятой, скобки и т.д. — все они являются важной частью синтаксиса (правил) языка. Хорошая новость заключается в том, что Python имеет более доступный и менее объемный синтаксис по сравнению с большинством других языков программирования: текст кажется почти понятным — как и рецепт.
Пример 1.2 — тоже небольшая программа на Python: она позволяет выбрать одно из заклинаний Гарри Поттера, хранящееся в списке, и вывести его на экран.
Пример 1.2. spells.py
spells = [
"Riddikulus!",
"Wingardium Leviosa!",
"Avada Kedavra!",
"Expecto Patronum!",
"Nox!",
"Lumos!",
]
print(spells[3])
Отдельные заклинания являются в Python строками (последовательностями текстовых символов, заключенных в кавычки). Они разделены запятыми и помещены в список — это можно определить по квадратным скобкам ([ и ]). Слово spells — это переменная, являющаяся именем списка, — с ее помощью мы можем работать со списком. В нашем случае на экран будет выведено четвертое заклинание:
Expecto Patronum!
Почему мы сказали 3, если нам нужно было четвертое заклинание? Списки Python, такие как spells, представляют собой последовательность значений, доступ к которым осуществляется с использованием смещения от начала списка. Смещение для первого элемента списка равно 0, а для четвертого — 3.
Люди обычно считают с единицы, поэтому считать с нуля может показаться странным. Однако в программировании удобнее оперировать смещениями, а не позициями. Да, это пример того, как компьютерная программа иногда отличается от обычного языка.
Список — очень распространенная структура данных в языке программирования Python. О том, как им пользоваться, будет рассказано в главе 7.
Программа из примера 1.3 выводит на экран цитату одного из участников комедийного трио The Three Stooges («Три балбеса»), однако на выбор фразы влияет не позиция в списке, а то, кто ее сказал.
Пример 1.3. quotes.py
quotes = {
"Moe": "A wise guy, huh?",
"Larry": "Ow!",
"Curly": "Nyuk nyuk!",
}
stooge = "Curly"
print(stooge, "says:", quotes[stooge])
Если вы запустите эту небольшую программу, она выведет следующее:
Curly says: Nyuk nyuk!
quotes — переменная, которая именует словарь Python: коллекцию уникальных ключей (в примере ключом является имя участника трио) и связанных с ними значений (в нашем примере — значимое высказывание участника «Балбесов»). Используя словарь, вы можете сохранять элементы и выполнять их поиск по именам: зачастую это удобнее, чем работать со списком.
В примере с заклинаниями для создания списка использовались квадратные скобки ([ и ]), а в примере с цитатами для создания словаря — фигурные скобки ({ и }). Также мы использовали двоеточие (:) для того, чтобы связать каждый ключ словаря с соответствующим значением. Более подробно о словарях можно прочитать в главе 8.
Надеюсь, я не перегрузил вас синтаксисом. В следующих нескольких разделах вы познакомитесь и с другими простыми правилами.
Более объемная программа
Теперь рассмотрим что-то совершенно иное: в примере 1.4 представлена программа, которая выполняет более сложную серию задач. Не рассчитывайте, что сразу поймете, как она работает, — книга для того и предназначена, чтоб научить вас этому! Таким образом я даю вам возможность увидеть и прочувствовать типичную полноразмерную программу, написанную на языке Python. Если вы знаете другие языки программирования, то можете сравнить их с Python прямо сейчас. Сможете ли вы, не зная Python и еще не прочтя расшифровку, примерно представить, что делает каждая строка? Вы уже видели примеры использования списка и словаря, а эта программа демонстрирует еще несколько новых возможностей.
В первом издании книги программа из примера подключалась к сайту YouTube и получала информацию о самых популярных роликах, таких как Charlie Bit My Finger. Она хорошо работала до того момента, как компания Google отключила поддержку этой службы. Во втором издании уже в новом примере (пример 1.4) мы подключаемся к другому сайту, который, очевидно, просуществует гораздо дольше, — Wayback Machine из Internet Archive (http://archive.org/) (бесплатного сервиса, сохраняющего миллиарды веб-страниц, в том числе фильмы, телешоу, музыкальные композиции, игры и иные цифровые артефакты за последние 20 лет). Еще несколько примеров таких веб-API вы увидите в главе 18.
Программа попросит вас ввести URL и дату. Затем она спросит у Wayback Machine, имеется ли копия этого веб-сайта за указанную дату. Если копия есть, API вернет информацию о ней программе, которая, в свою очередь, выведет URL и отобразит его в веб-браузере. Суть заключается в том, чтобы увидеть, как Python справляется с разнообразными задачами — принимает пользовательские данные, общается с веб-сайтами в Интернете и получает от них данные, извлекает оттуда URL и убеждает веб-браузер отобразить этот URL.
Если бы мы получали обычную веб-страницу, заполненную текстом, отформатированным как HTML, нам пришлось бы сначала придумать, как отобразить ее, а потом выполнить много действий — все это можно радостно перепоручить веб-браузеру. Мы также можем попробовать извлечь именно те данные, которые нам нужны (более подробно о веб-скрапинге читайте в главе 18). Любой из выбранных вариантов потребует выполнения большего количества работы и увеличит программу. Вместо этого Wayback Machine возвращает данные в формате JSON. JSON, или JavaScript Object Notation, — это читабельный для человека текстовый формат, который описывает типы и значения, а также выстраивает данные в определенном порядке. Он немного похож на языки программирования и уже стал популярным способом обмена данными между разными языками программирования и системами. Подробнее о JSON вы узнаете в главе 12.
Программы, написанные на языке Python, могут преобразовывать текст формата JSON в структуры данных (с которыми вы познакомитесь в следующих нескольких главах), как если бы вы написали программу для их создания самостоятельно. Наша небольшая программа выбирает лишь один фрагмент данных (URL старой веб-страницы, хранящейся в архиве). И опять же это полноценная программа, которую вы можете запустить самостоятельно. Мы почти не проверяли данные на ошибки, чтобы пример оставался коротким. Номера строк не являются частью программы и включены только для того, чтобы вам было проще следовать описанию, представленному после кода.
Пример 1.4. archive.py
1 import webbrowser
2 import json
3 from urllib.request import urlopen
4
5 print("Let's find an old website.")
6 site = input("Type a website URL: ")
7 era = input("Type a year, month, and day, like 20150613: ")
8 url = "" % (site, era)
9 response = urlopen(url)
10 contents = response.read()
11 text = contents.decode("utf-8")
12 data = json.loads(text)
13 try:
14 old_site = data["archived_snapshots"]["closest"]["url"]
15 print("Found this copy: ", old_site)
16 print("It should appear in your browser now.")
17 webbrowser.open(old_site)
18 except:
19 print("Sorry, no luck finding", site)
Такая небольшая программа, написанная на языке Python, делает многое с помощью всего нескольких строк. Не все термины вы уже знаете, однако сможете познакомиться с ними в следующих главах.
1. Импортируем (делаем доступным для этой программы) весь код из модуля стандартной библиотеки, который называется webbrowser.
2. Импортируем весь код из модуля стандартной библиотеки, который называется json.
3. Импортируем только функциюurlopen из модуля стандартной библиотеки urllib.request.
4. Пустая строка (мы не хотим перегрузить восприятие).
5. Выводим на экран приветственный текст.
6. Выводим на экран вопрос об URL, считываем пользовательский ввод и сохраняем это в переменной с именем site.
7. Выводим на экран еще один вопрос и на этот раз считываем год, месяц и день, а затем сохраняем их в переменной с именем era.
8. Создаем строковую переменную с именем url, чтобы сайт Wayback Machine искал копию требуемого сайта по дате.
9. Соединяемся с сервером, расположенным по этому адресу, и запрашиваем определенный веб-сервис.
10. Получаем ответ и присваиваем его переменной contents.
11. Дешифруем содержимое переменной contents в текстовую строку формата JSON и приписываем ее переменной text.
12. Преобразуем переменную text в data — структуру данных языка Python, предназначенную для работы с видео.
13. Проверяем на ошибки: помещаем следующие четыре строки в блок try и, если находим ошибку, запускаем последнюю строку программы (она идет после ключевого слова except).
14. Получив совпадение по сайту и дате, извлекаем нужное значение из трехуровневого словаря Python. Обратите внимание на то, что в этой и двух последующих строках используются отступы — тем самым Python легче понять, что данные строки находятся в блоке try.
15. Выводим на экран полученный URL.
16. Сообщаем о том, что случится, когда выполнится следующая строка.
17. Отображаем полученный URL в браузере.
18. Если во время выполнения предыдущих строк что-то пошло не так, Python перейдет сюда.
19. Если программа дала сбой, выводим сообщение и имя сайта, который мы искали. Эта строка также имеет отступ, поскольку должна выполняться только в том случае, если выполняется строка except.
Когда я сам запустил эту программу в окне терминала, то ввел URL сайта и дату и получил следующий результат:
$ python archive.py
Let's find an old website.
Type a website URL: lolcats.com
Type a year, month, and day, like 20150613: 20151022
Found this copy: http://web.archive.org/web/20151102055938/http://www.lolcats.com/
It should appear in your browser now.
На рис. 1.3 показано то, что появилось в моем браузере.
Рис. 1.3. Результат обращения к Wayback Machine
В предыдущем примере мы задействовали стандартные библиотечные модули (программы, включаемые в Python при установке), но совсем не обязательно ограничиваться только ими: на языке Python написано много отличного стороннего ПО. В примере 1.5 показывается та же программа, получающая доступ к архиву Интернета (Internet Archive), но в ней использован внешний пакет ПО для Python, который называется requests.
Пример 1.5. archive2.py
1 import webbrowser
2 import requests
3
4 print("Let's find an old website.")
5 site = input("Type a website URL: ")
6 era = input("Type a year, month, and day, like 20150613: ")
7 url = "" % (site, era)
8 response = requests.get(url)
9 data = response.json()
10 try:
11 old_site = data["archived_snapshots"]["closest"]["url"]
12 print("Found this copy: ", old_site)
13 print("It should appear in your browser now.")
14 webbrowser.open(old_site)
15 except:
16 print("Sorry, no luck finding", site)
Новая версия короче и, как мне кажется, более читабельна для большинства людей. О requests вы узнаете в главе 18, а о других авторских программах для Python в главе 11.
Python в реальном мире
Стоит ли тратить время и силы на изучение Python? Язык программирования Python существует примерно с 1991 года (он старше Java, но моложе С) и является одним из пяти самых популярных языков программирования. Людям платят деньги за написание программ на Python — очень важных и значимых, которыми мы пользуемся каждый день: Google, YouTube, Instagram, Netflix и Hulu.
Я использовал Python для создания приложений в самых разных областях. Python имеет репутацию высокопроизводительного языка программирования, и это особенно нравится динамично развивающимся компаниям.
Python используется во многих компьютерных приложениях, таких как:
• командная строка на мониторе или в окне терминала;
• пользовательские интерфейсы (Graphical User Interface, GUI), включая сетевые;
• веб-приложения, как клиентские, так и серверные;
• бэкенд-серверы, поддерживающие крупные популярные сайты;
• облака (серверы, управляемые сторонними организациями);
• приложения для мобильных устройств;
• приложения для встроенных устройств.
Программы, написанные на Python, могут быть как одноразовыми сценариями — вы видели их ранее в этой главе, так и сложными системами, содержащими миллионы строк.
В опросе The 2018 Python Developers’ Survey (https://www.jetbrains.com/research/python-developers-survey-2018/) вы можете увидеть числа и графики, показывающие текущее место языка Python в мире вычислительных машин.
Мы рассмотрим применение Python для создания сайтов, системного администрирования и манипулирования данными. Рассмотрим также использование Python в искусстве, науке и бизнесе.
Python против языка с планеты Х
Насколько Python хорош по сравнению с другими языками программирования? Где и когда следует использовать тот или иной язык? В этом разделе я покажу примеры кода, написанные на других языках, чтобы вы могли оценить, с чем конкурирует Python. Вы не обязаны понимать каждый из приведенных фрагментов, если не работали с этими языками. (А когда увидите последний фрагмент, написанный на Python, то почувствуете облегчение из-за того, что не работали с некоторыми другими языками.) Если же вам интересен только Python — вы ничего не потеряете, если не станете читать этот раздел.
Каждая программа должна напечатать число и немного рассказать о языке, на котором она написана.
Если вы пользуетесь терминалом или терминальным окном, программа, которая читает то, что вы вводите, выполняет это и отображает результат, называется программой-оболочкой. Оболочка операционной системы Windows называется cmd (https://ru.wikipedia.org/wiki/Cmd.exe), она выполняет пакетные файлы, имеющие расширение .bat. Для Linux и других операционных систем семейства Unix (включая macOS) существует множество программ-оболочек. Самая популярная из них называется bash (https://www.gnu.org/software/bash/) или sh. Оболочка обладает простейшими возможностями вроде выполнения простой логики и разворачивания символа-джокера наподобие * в полноценные имена файлов. Вы можете сохранять команды в файлы, которые называются сценариями оболочки, и выполнять их позже. Подобные программы могли быть в числе самых первых в вашей карьере программиста. Проблема в том, что возможности для масштабирования у сценариев оболочки ограничиваются несколькими сотнями строк, а сами сценарии выполняются гораздо медленнее, чем программы, написанные на других языках. В следующем фрагменте кода демонстрируется небольшая программа-оболочка:
#!/bin/sh
language=0
echo "Language $language: I am the shell. So there."
Если вы сохраните этот файл под именем test.sh и запустите его с помощью команды shtest.sh, то на экране увидите следующее:
Language 0: I am the shell. So there.
Старые добрые С (https://ru.wikipedia.org/wiki/Си_(язык_программирования)) и С++ (https://ru.wikipedia.org/wiki/C++) являются довольно низкоуровневыми языками программирования, которыми пользуются в том случае, когда важна скорость. Ваша операционная система и множество других программ (включая программу python на вашем компьютере), скорее всего, написаны на C и C++.
Эти языки программирования труднее выучить и труднее поддерживать знания в актуальном состоянии. Вам придется отслеживать множество деталей, таких как управление памятью, что может привести к падениям программы и проблемам, которые трудно диагностировать. Так выглядит небольшая программа на языке С:
#include <stdio.h>
int main(int argc, char *argv[]) {
int language = 1;
printf("Language %d: I am C! See? Si!\n", language);
return 0;
}
С++ происходит из одного семейства с С, но имеет несколько отличительных особенностей:
#include <iostream>
using namespace std;
int main() {
int language = 2;
cout << "Language " << language << \
": I am C++! Pay no attention my little brother!" << \
endl;
return(0);
}
Java (https://www.java.com/ru/) и C# (https://docs.microsoft.com/en-us/dotnet/csharp/) являются преемниками языков С и С++. Они избавлены от некоторых недостатков предшественников (особенно в управлении памятью), но при этом могут быть немного избыточными. Следующий пример написан на Java:
public class Anecdote {
public static void main (String[] args) {
int language = 3;
System.out.format("Language %d: I am Java! So there!\n", language);
}
}
Если вы никогда не писали ни на одном из этих языков, у вас может возникнуть вопрос, что все это такое? Ведь мы хотели всего лишь вывести на экран простую строку — действительно, некоторые языки нагружены значительным синтаксическим багажом. Подробнее об этом вы узнаете из главы 2.
С, С++ и Java являются примерами статических языков. Они требуют, чтобы вы указали компьютеру некоторые низкоуровневые детали, например типы данных. В приложении А говорится, что для разных типов данных выделяется разное количество памяти и для них можно выполнять лишь заранее определенный набор операций. Динамические языки (они также называются скриптовыми) — полная противоположность статическим, они не заставляют вас определять тип переменной перед тем, как ее использовать.
Многоцелевым динамическим языком многие годы был Perl (https://www.perl.org/), очень мощный и с обширными библиотеками. Однако его синтаксис достаточно труден для понимания, а сам язык теряет в популярности из-за появления языков программирования Python и Ruby. Следующий пример побалует вас острым привкусом Perl:
my $language = 4;
print "Language $language: I am Perl, the camel of languages.\n";
Язык программирования Ruby (http://www.ruby-lang.org/en/) появился немного позже. Он отчасти позаимствовал функционал у языка Perl, а свою популярность приобрел благодаря фреймворку для веб-разработки Ruby on Rails. Используется Ruby примерно в тех же областях, что и Python, и, выбирая между этими языками, вам придется руководствоваться в большей степени вкусом и доступностью библиотек. Следующий фрагмент кода написан на Ruby:
language = 5
puts "Language #{language}: I am Ruby, ready and aglow."
Язык программирования PHP (http://www.php.net/) из следующего примера очень популярен в области веб-разработок, поскольку позволяет довольно легко объединять HTML и код. Однако язык PHP имеет несколько подводных камней, и с ним довольно трудно работать за пределами сферы веб-разработок. Вот так выглядит программа, написанная на PHP:
<?PHP
$language = 6;
echo "Language $language: I am PHP, a language and palindrome.\n";
?>
Язык Go (https://golang.org/) (в поисковике лучше искать Golang) появился относительно недавно и пытается быть эффективным и быстрым:
package main
import "fmt"
func main() {
language := 7
fmt.Printf("Language %d: Hey, ho, let's Go!\n", language)
}
Еще одной современной альтернативой языкам С и С++ является Rust (https://www.rust-lang.org/learn):
fn main() {
println!("Language {}: Rust here!", 8)
Кто остался? Ах да, Python (https://www.python.org/):
language = 9
print(f"Language {language}: I am Python. What's for supper?")
Почему же Python?
Одной из причин, не обязательно самой важной, является популярность. Есть такие факты:
• Python — это наиболее быстро набирающий популярность основной язык программирования, как показано на рис. 1.4 (https://stackoverflow.blog/2017/09/06/incredible-growth-python/);
• редакторы TIOBE Index (https://www.tiobe.com/tiobe-index/) в июне 2019 года заявили: «В этом месяце Python снова достиг высочайшей позиции в TIOBE Index, его результат составил 8,5 %. Если Python удержит такой темп, то в течение ближайших трех-четырех лет он сможет заменить С и Java, став самым популярным языком программирования в мире»;
• Python стал языком программирования 2018 года по версии TIOBE и занял первые места в рейтингах IEEE Spectrum (https://spectrum.ieee.org/at-work/innovation/the-2018-top-programming-languages) и PyPL (http://pypl.github.io/PYPL.html);
• Python является самым популярным языком программирования для курсов введения в информатику в лучших американских колледжах (https://cacm.acm.org/blogs/blog-cacm/176450-python-is-now-the-most-popular-introductory-teaching-language-at-top-u-s-universities/fulltext);
• Python официально используется для обучения во французских гимназиях.
Рис. 1.4. Python опережает в росте остальные основные языки программирования
В последнее время Python стал чрезвычайно популярным языком программирования в науке о данных и машинном обучении. Если вы хотите получить высокооплачиваемую работу разработчика в интересной области, Python — хороший выбор. А если вы занимаетесь набором персонала, имейте в виду, что пул опытных разработчиков на Python постоянно растет.
Но почему Python так популярен? Ведь языки программирования не имеют харизмы. В чем же причина?
Python — многоцелевой высокоуровневый язык программирования. Его дизайн позволяет писать хорошо читаемый код, что на самом деле гораздо важнее, чем кажется на первый взгляд. Каждая компьютерная программа пишется всего однажды, но впоследствии к ней обращаются множество раз. Благодаря удобочитаемости программу легко запомнить, а также легко ее воспроизвести. По сравнению с другими популярными языками программирования кривая обучения языку Python более гладкая, что позволяет ученику быстрее стать продуктивным. Однако есть и сложные моменты, с которыми вы столкнетесь по мере приобретения опыта.
Относительный лаконизм языка Python позволяет создавать гораздо более короткие программы — аналогичная программа, но написанная на статическом языке, будет намного длиннее. Исследования показали, что программисты пишут примерно одинаковое количество строк кода каждый день независимо от языка, поэтому Python может значительно повысить вашу продуктивность. Язык программирования Python — самое несекретное оружие многих компаний, которым важна продуктивность работы сотрудников.
С помощью Python вы можете написать все, что хотите, и совершенно бесплатно использовать это где угодно. Никто не скажет, прочитав вашу программу: «Ах, какая милая программка! Будет жаль, если с ней что-нибудь случится».
Python запускается практически везде и имеет «встроенные батарейки» — огромное количество разнообразного ПО в стандартных библиотеках. В этой книге имеется множество примеров использования стандартной библиотеки и полезного стороннего кода.
Но основная причина использования Python вам, возможно, покажется неожиданной: как правило, люди любят работать с этим языком, а не рассматривают его как необходимое зло для решения задачи — он подходит их образу мышления. Часто разработчики, когда им приходится программировать на другом языке, говорят, что им не хватает какой-то возможности Python. И это выделяет Python на фоне всех его «коллег».
Когда не стоит использовать Python
Python не всегда будет наилучшим выбором.
Он не установлен по умолчанию. В приложении Б показано, как установить Python, если он еще не установлен на вашем компьютере.
Python достаточно быстрый для большинства приложений, но его скорости может оказаться недостаточно для наиболее требовательных из них. Если ваша программа проводит большую часть времени за вычислениями, что в технических терминах называется «ограничена быстродействием процессора (CPU-bound)», то языки С, С++, Java, Rust или Go справятся с задачей гораздо лучше, чем Python. Но не всегда!
Учтите следующие обстоятельства.
• Иногда более качественный алгоритм (пошаговое решение) в Python превосходит неэффективный алгоритм в С. Более высокая скорость разработки в Python дает больше времени для экспериментов в поисках альтернативных решений.
• Во многих приложениях (особенно в веб-приложениях) программа «бьет баклуши» в ожидании ответа от сервера. Центральный процессор (компьютерный чип, который делает все расчеты) обычно не задействован, поэтому время выполнения статических и динамических программ будет примерно одинаковым.
• Стандартный интерпретатор Python написан на С и может быть улучшен с помощью дополнительного кода. Я рассмотрю этот вопрос в главе 19.
• Интерпретаторы Python становятся быстрее. Java, когда только появился, был чрезвычайно медленным, и на его ускорение ушло много времени и денег. Языком программирования Python не владеет ни одна корпорация, поэтому он улучшается последовательно и более плавно. В подразделе «PyPy» на с. 465 я расскажу о проекте PyPy и его приложениях.
• У вас в работе может быть очень сложное приложение, и тогда, независимо от того, что вы делаете, Python не сможет удовлетворить все ваши требования. Обычной альтернативой в таком случае являются языки программирования С, С++ и Java. Вы также можете рассмотреть возможность использования языка Go (http://golang.org/), который выглядит как Python, но работает как С, или языка Rust.
Python 2 против Python 3
Вы можете столкнуться с проблемой выбора одной из двух версий Python. Python 2 существует давно и предустановлен на компьютерах с Linux и Apple. Это был отличный язык, но нет ничего идеального. В языках программирования, как и во многих других сферах, бывают ошибки косметические и легко исправимые, а бывают — сложные и требующие усилий. Исправления несовместимы: новые программы, написанные с помощью исправленного языка, не будут работать на старых системах, а старые программы не будут работать на новых.
Создатель языка Python Гвидо ван Россум (https://www.python.org/~guido) и другие разработчики решили собрать и объединить все исправления и в результате в 2008 году представили миру Python 3. Python 2 — это прошлое, а Python 3 — будущее. Финальная версия Python 2 имеет номер 2.7, и некоторое время она еще будет поддерживаться, однако на ней род заканчивается; Python 2.8 никогда не выйдет. Окончание поддержки языка Python 2 намечено на январь 2020 года. Больше не будут исправляться проблемы (в том числе проблемы с безопасностью), и многие весомые пакеты Python к этому моменту перестанут поддерживать Python 2 (https://python3statement.org/). В операционных системах также будет отключен Python 2 и, скорее всего, подключен Python 3 в качестве нового языка, используемого по умолчанию. Преобразование популярного ПО в Python 3 было постепенным, но переломный момент уже произошел и новые разработки будут вестись на Python 3.
Эта книга посвящена Python 3. Он выглядит практически так же, как и Python 2. Самое очевидное изменение — это тот факт, что print в Python 3 является функцией, поэтому вам нужно вызывать ее с помощью круглых скобок, в которых будут перечислены аргументы. А самое главное изменение — это обработка символов Unicode (она рассматривается в главе 12). На протяжении всей книги я буду обращать ваше внимание и на другие различия.
Установка Python
Чтобы не загромождать текст, я вынес детали установки Python 3 в приложение Б. Если у вас еще не установлен Python 3 или вы не до конца в этом уверены, обратитесь к приложению и посмотрите, каковы должны быть ваши действия. Да, это может быть хлопотно и трудоемко, но сделать это вам придется лишь однажды.
Запуск Python
После установки рабочей копии Python 3 вы сможете использовать ее, чтобы запускать как приведенные в этой книге программы, так и собственный код. Как же запустить программу, написанную на языке Python? Существует два основных способа.
• Встроенный в Python интерактивный интерпретатор (также он называется оболочкой) предоставляет простой способ поэкспериментировать с небольшими программами. Строка за строкой вы вводите команды и мгновенно видите результат — такая тесная связь между набором текста и его просмотром позволяет проводить эксперименты быстрее. Я буду использовать интерактивный интерпретатор для демонстрации возможностей языка, а вы те же команды можете вводить в собственном компьютере.
• В остальных случаях сохраняйте программы в виде текстовых файлов с расширением .py, а затем запускайте их, введя python и имена этих файлов.
Попробуем воспользоваться обоими методами.
Интерактивный интерпретатор
Для большинства примеров кода в этой книге используется встроенный интерактивный интерпретатор. Когда вы вводите команду из примера и получаете тот же результаты, вы понимаете, что находитесь на правильном пути.
Интерпретатор запускается путем ввода имени основной программы Python для вашего компьютера: python, python3 или чего-то похожего. В дальнейшем мы будем предполагать, что она называется python. Если ваша программа называется по-другому, то для запуска вам следует ввести именно ее имя.
Интерактивный интерпретатор работает практически так же, как и интерпретатор для файлов, за одним исключением: когда вы вводите обычное значение, интерактивный интерпретатор автоматически выводит его на экран. Это не часть языка Python, а всего лишь особенность интерпретатора, которая позволяет вам сэкономить немного времени, не набирая конструкцию print() каждый раз. Например, если вы запустите Python и введете в интерпретатор число 27, оно будет продублировано в терминале (если в вашем файле есть строка 27, Python не расстроится, но при запуске программы вы не увидите ничего):
$ python
Python 3.7.2 (v3.7.2:9a3ffc0492, Dec 24 2018, 02:44:43)
[Clang 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 27
27
В предыдущем примере символ $ — это обычное приглашение ввести команду вроде python в окно терминала. Мы будем использовать ее для примеров кода в этой книге, однако ваше приглашение может отличаться.
Кстати, функция print() также работает внутри интерпретатора, на случай если вам понадобится вывести что-то на экран:
>>> print(27)
27
Если вы попробовали запустить эти примеры с помощью интерактивного интерпретатора и увидели те же результаты, то у вас появился опыт (пусть и небольшой) запуска кода на Python. В следующих нескольких главах вы перейдете от строковых команд к более длинным программам.
Файлы Python
Если вы запишете в файл число 27 и запустите этот файл с помощью Python, он выполнится, но на экране ничего не появится. В обычных неинтерактивных программах для Python вам нужно вызывать функцию print, чтобы вывести что-то на экран, как показано в следующем фрагменте кода:
print(27)
Создадим файл программы Python и запустим его.
1. Откройте текстовый редактор.
2. Введите в него строку print(27), как это показано здесь.
3. Сохраните этот файл с именем test.py. Убедитесь, что вы сохранили его как простой текст, а не в формате вроде RTF или DOC. Вы не обязаны использовать расширение .py для файлов программ Python, но оно поможет вам запомнить предназначение файла.
4. Если вы пользуетесь графическим пользовательским интерфейсом — это касается практически каждого, — откройте окно терминала5.
5. Запустите программу, введя следующую строку:
$ python test.py
Вы должны увидеть такую строку:
27
Сработало? Если да, то примите мои поздравления по поводу того, что вы запустили свою первую автономную программу на Python!
Что дальше?
Вы будете вводить команды в работающую систему Python, и они должны соответствовать синтаксису языка. Вместо того чтобы сваливать на вас все синтаксические правила сразу, мы неторопливо пройдемся по ним в нескольких следующих главах.
Базовый способ разработки программы на Python — применение простого текстового редактора и окна терминала. В рамках этой книги я использую именно такие редакторы, иногда показывая интерактивные сессии работы с терминалом, а иногда — фрагменты файлов. Вам следует знать, что существует множество интегрированных сред разработки (integrated development environment, IDE) для Python. Они могут предоставить вам графические пользовательские интерфейсы, помогающие в редактировании текста, и экраны помощи. Более подробно об этом вы прочитаете в главе 19.
Момент просветления
Каждый язык программирования имеет свой стиль. Во введении я упомянул, что существует характерный для Python способ выразить себя. В Python встроен небольшой текст, который выражает его философию (насколько я знаю, Python — это единственный язык программирования, содержащий подобную «пасхалку»). Когда вам захочется ощутить момент просветления, просто введите importthis в интерактивный интерпретатор, а затем нажмите клавишу Enter:
>>> import this
Красивое лучше, чем уродливое.
Явное лучше, чем неявное.
Простое лучше, чем сложное.
Сложное лучше, чем запутанное.
Одноуровневое лучше, чем вложенное.
Разреженное лучше, чем плотное.
Читаемость имеет значение.
Особые случаи не настолько особые, чтобы нарушать правила.
При этом практичность важнее безупречности.
Ошибки никогда не должны замалчиваться.
Если не замалчиваются явно.
Встретив двусмысленность, отбрось искушение угадать.
Должен существовать один — и желательно только один — очевидный способ сделать это.
Хотя поначалу он может быть и неочевиден, если вы не голландец.
Сейчас лучше, чем никогда.
Хотя никогда зачастую лучше, чем прямо сейчас.
Если реализацию сложно объяснить — идея плоха.
Если реализацию легко объяснить — идея, возможно, хороша.
Пространства имен — отличная штука! Будем делать их побольше!
На протяжении всей книги я буду приводить примеры, иллюстрирующие эти утверждения.
Читайте далее
В следующей главе мы поговорим о типах данных и переменных в Python. Это подготовит вас к чтению тех глав, в которых подробно рассматриваются типы данных и структуры кода Python.
Упражнения
Эта глава была введением в язык программирования Python. Вы узнали, что язык делает, как выглядит и где его можно применить. В конце каждой главы я буду предлагать выполнить небольшие задания, которые помогут вам запомнить то, что вы только что прочитали, и подготовят к следующим урокам.
1.1. Если вы еще не установили Python 3, сделайте это сейчас. Прочтите приложение Б, чтобы узнать детали.
1.2. Запустите интерактивный интерпретатор Python 3. Детали опять же вы найдете в приложении Б. Интерпретатор должен вывести несколько строк о себе, а затем строку, начинающуюся с символов >>>. Перед вами приглашение для ввода команд Python.
1.3. Немного поэкспериментируйте с интерпретатором. Используйте его как калькулятор и наберите 8*9. Нажмите клавишу Enter, чтобы увидеть результат. Python должен вывести 72.
1.4. Теперь введите число 47 и нажмите клавишу Enter. Появилось ли число 47 в следующей строке?
1.5. Теперь введите print(47) и нажмите клавишу Enter. Появилось ли снова число 47 в следующей строке?
5 Если вы не знаете, что это значит, откройте приложение Б, чтобы получить детальную информацию для различных операционных систем.
4. Если вы пользуетесь графическим пользовательским интерфейсом — это касается практически каждого, — откройте окно терминала5.
Если вы не знаете, что это значит, откройте приложение Б, чтобы получить детальную информацию для различных операционных систем.
Глава 2. Данные: типы, значения, переменные и имена
Доброе имя лучше большого богатства.
Притчи 22:1
Все, что хранится в компьютере, представляет собой лишь последовательность битов (приложение А). Одно из преимуществ вычислительной техники заключается в том, что мы можем интерпретировать эти биты любым удобным нам способом — как данные всевозможного размера и типов (например, как числа или текстовые символы) или даже как компьютерный код. Мы используем Python для определения наборов этих битов, соответствующих разным задачам, а также для отправки их в процессор и получения обратно.
Мы начнем с типов данных, используемых в Python, и значений, которые они могут содержать. Затем рассмотрим, как представить данные в виде значений-литералов и переменных.
В Python данные являются объектами
Память вашего компьютера визуально можно представить в виде длинного ряда полок. Каждый слот на этих полках имеет ширину 1 байт (8 бит). Слоты пронумерованы от 0 (первая позиция) до самого конца. Современные компьютеры имеют миллиарды байт памяти (гигабайт), поэтому полки могли бы заполнить огромный воображаемый склад.
Программа Python получает доступ к определенной области памяти вашего компьютера с помощью операционной системы. Эта память используется для кода самой программы, а также для данных, которыми программа оперирует. Операционная система гарантирует, что программа не может читать или записывать в другие области памяти без соответствующего разрешения.
Программы следят за тем, где (область памяти) хранятся их биты и чем (тип данных) они являются. С точки зрения вашего компьютера все биты одинаковы. Одни и те же биты могут иметь разные значения в зависимости от того, какого они типа. Один и тот же вариант расстановки битов может означать как число 65, так и текстовый символ А.
Разные типы используют разное количество битов. Когда вы читаете о «64-битной машине», это означает, что целое число использует 64 бита (8 байт).
Некоторые языки хранят эти необработанные значения в памяти, отслеживая их размеры и типы. Вместо непосредственной обработки таких данных Python упаковывает каждое значение — булевы значения, целые числа, числа с плавающей точкой, строки и даже крупные структуры данных, функции и программы — в память как объекты. Глава 10 этой книги посвящена созданию собственных объектов в Python, но сейчас мы поговорим только об объектах, которые обрабатывают встроенные типы данных.
Продолжая аналогию с полками: можно представить, что объекты — это коробки переменной длины, занимающие место на этих полках так, как показано на рис. 2.1. Python создает такие коробки, размещает их на свободных местах и убирает, когда потребность в них отпадает.
Рис. 2.1. Похожий на коробку объект — целое число со значением 7
В Python объектом является фрагмент данных, в котором содержится как минимум следующее:
•тип, определяющий, что объект может делать (подробнее см. в следующем разделе);
• уникальный идентификатор, позволяющий отличить его от других объектов;
• значение, соответствующее типу;
• счетчик ссылок для отслеживания того, как часто объект используется.
Идентификатор представляет собой адрес места на полке. Тип похож на фабричный штамп на коробке, который поясняет, что объект может делать. Если объект является целым числом, он имеет тип int и может (помимо всего прочего, о чем вы узнаете из главы 3) быть добавлен к другому объекту с типом int. Если мы представим, что коробка сделана из прозрачного пластика, то сможем увидеть значение, находящееся внутри нее. О том, зачем нужен счетчик ссылок, вы узнаете через несколько разделов, когда мы будем говорить о переменных и именах.
Типы
В табл. 2.1 представлены базовые типы данных в Python. Во втором столбце («Тип») содержится имя этого типа в Python. Третий столбец («Изменяемый?») указывает, можно ли изменить значение переменной после ее создания (подробнее об этом поговорим в следующем разделе). В столбце «Примеры» показываются один или несколько примеров-литералов, соответствующих этому типу. И последний столбец («Глава») указывает на главу этой книги с наиболее подробной информацией о данном типе.
Таблица 2.1. Базовые типы данных в Python
| Имя |
Тип |
Изменяемый? |
Примеры |
Глава |
| Булево значение |
bool |
Нет |
True, False |
Глава 3 |
| Целое число |
int |
Нет |
47, 25000, 25_000 |
Глава 3 |
| Число с плавающей точкой |
float |
Нет |
3.14, 2.7e5 |
Глава 3 |
| Комплексное число |
complex |
Нет |
3j, 5 + 9j |
Глава 22 |
| Текстовая строка |
str |
Нет |
'alas', "alack", '''a verse attack''' |
Глава 5 |
| Список |
list |
Да |
['Winken', 'Blinken', 'Nod'] |
Глава 7 |
| Кортеж |
tuple |
Нет |
(2, 4, 8) |
Глава 7 |
| Байты |
bytes |
Нет |
b'ab\xff' |
Глава 12 |
| Массив байтов |
bytearray |
Да |
bytearray(…) |
Глава 12 |
| Множество |
set |
Да |
set([3, 5, 7]) |
Глава 8 |
| Фиксированное множество |
frozenset |
Нет |
frozenset(['Elsa', 'Otto']) |
Глава 8 |
| Словарь |
dict |
Да |
{'game': 'bingo', 'dog': 'dingo', 'drummer': 'Ringo'} |
Глава 8 |
После глав, посвященных этим базовым типам, в главе 10 вы узнаете, как создавать новые типы данных.
Изменчивость
Изменчивость одна лишь неизменна.
Перси Шелли
Тип также определяет, можно ли значение, которое хранится в ящике, изменить — тогда это будет изменяемоезначение, или оно константно — неизменяемое значение. Неизменяемый объект как будто находится в закрытом ящике с прозрачными стенками (см. рис. 2.1): увидеть значение вы можете, но не в силах его изменить. По той же аналогии изменяемый объект похож на коробку с крышкой: вы можете не только увидеть хранящееся там значение, но и изменить его, не изменив его тип.
Python является сильно типизированным языком, а это означает, что тип объекта не изменяется, даже если его значение изменяемо (рис. 2.2).
Рис. 2.2. Сильная типизация не означает, что клавиши нужно нажимать сильнее
Значения-литералы
Существует два вида определения данных в Python:
• как литералы;
• как переменные.
В следующих главах вы увидите, как указываются значения-литералы для разных типов данных — целые числа представляют собой последовательность цифр, дробные числа содержат десятичную точку, текстовые строки заключаются в кавычки и т.д. Но в примерах этой главы — чтобы избежать излишней сложности — мы будем использовать лишь короткие целые числа из десятичной системы счисления и один-два списка. Десятичные целые числа такие же, как числа в математике: они представляют собой последовательность цифр от 0 до 9. В главе 3 мы рассмотрим дополнительные детали работы с целыми числами (например, знаки и недесятичные системы счисления).
Переменные
Вот мы и добрались до ключевого понятия языков программирования.
Python, как и большинство других компьютерных языков, позволяет вам определять переменные — имена для значений в памяти вашего компьютера, которые вы далее будете использовать в программе.
Имена переменных в Python отвечают определенным правилам.
• Они могут содержать только следующие символы:
• буквы в нижнем регистре (от a до z);
• буквы в верхнем регистре (от A до Z);
• цифры (от 0 до 9);
• нижнее подчеркивание (_).
• Они чувствительны к регистру: thing, Thing и THING — это разные имена.
• Они должны начинаться с буквы или нижнего подчеркивания, но не с цифры.
• Python особо обрабатывает имена, которые начинаются с нижнего подчеркивания (об этом вы сможете прочитать в главе 9).
• Они не могут совпадать с зарезервированными словами Python (их также называют ключевыми).
Перед вами список зарезервированных6 слов:
False await else import pass
None break except in raise
True class finally is return
and continue for lambda try
as def from nonlocal while
assert del global not with
async elif if or yield
Внутри программы Python увидеть список зарезервированных слов можно с помощью команд:
>>> help("keywords")
или:
>>> import keyword
>>> keyword.kwlist
Корректными являются такие имена:
•a;
• a1;
• a_b_c___95;
• _abc;
•_1a.
А следующие имена некорректны:
•1;
• 1a;
• 1_;
• name!;
•another-name.
Присваивание
В Python символ = применяется для присваивания значения переменной.
В школе нас учили, что символ = означает «равно». Почему же во многих языках программирования, включая Python, этот символ используется для обозначения присваивания? Одна из причин — на стандартной клавиатуре отсутствуют логические альтернативы вроде стрелки влево, а символ = не слишком сбивает с толку. Кроме того, в компьютерных программах присваивание используется чаще, чем проверка на равенство.
Программы непохожи на алгебру. В школе мы имели дело с подобными уравнениями:
y = x + 12
Решить уравнение можно, подставив значение для x. Если вы зададите для x значение 5, то, поскольку 5+12 равно 17, значение y будет равно 17. Подставьте значение 6, и y будет равен 18. И так далее.
Строки компьютерной программы могут выглядеть как уравнения, но означают они при этом нечто иное. В Python и других компьютерных языках x и y являются переменными. Python знает, что цифра или простая последовательность цифр вроде 12 или 5 является числовым литералом. Рассмотрим небольшую программу на Python, которая схожа с этим уравнением, — она выводит на экран значение y:
>>> x = 5
>>> y = x + 12
>>> y
17
Здесь мы видим большое различие между математикой и программами: в математике знак = означает равенство обеих сторон, а в программировании он означает присваивание: переменной слева мы присваиваем значение с правой стороны.
В программировании также принято, что все находящееся справа от знака = должно иметь значение (это называется инициализацией). Справа вы можете увидеть значение-литерал, переменную, которой было присвоено значение, или их комбинацию. Python знает, что 5 и 12 — это числовые литералы. В первой строке целочисленное значение 5 присваивается переменной х. Теперь мы можем использовать переменную х в следующей строке. Когда Python читает выражение y=x+12, он делает следующее:
• видит знак = в середине;
• понимает, что это оператор присваивания;
• вычисляет значение с правой стороны (получает значение объекта, на который ссылается переменная х, и добавляет его к 12);
• присваивает этот результат переменной слева — y.
Теперь, введя имя у в интерактивном интерпретаторе, можно увидеть его новое значение.
Если вы начнете программу со строки y=x+12, Python сгенерирует исключение (ошибку), поскольку переменная х еще не имеет значения:
>>> y = x + 12
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
Более подробно об исключениях можно прочитать в главе 9. На компьютерном языке мы скажем, что переменная хне была инициализирована.
В алгебре вы могли бы сделать все наоборот — присвоить значение у, чтобы подсчитать значение х. Для того, чтобы сделать это в Python, вам нужно получить значения-литералы и инициализированные переменные с правой стороны оператора присваивания до того, как присвоить значение переменной х:
>>> y = 5
>>> x = 12 - y
>>> x
7
Переменные — это имена, а не локации
Пришло время сделать важное утверждение о переменных в Python: переменные — всего лишь имена, и в этом заключается отличие Python от других языков программирования. Об этом важно помнить, особенно при работе с такими изменяемыми объектами, как списки. Операция присваивания не копирует значение, а только лишь прикрепляет имя к объекту, содержащему нужные данные. Имя — это ссылка на объект, а не сам объект. Можно представить, что имя — это этикетка, приклеенная на коробку с объектом, которая размещается где-то в памяти компьютера (рис. 2.3).
В других языках программирования переменные сами по себе имеют тип и привязываются к локации в памяти. Вы можете изменить значение в этой локации, но оно должно быть того же типа. Именно поэтому в статических языках нужно объявлять тип переменных. В Python этого делать не требуется, поскольку имя может ссылаться на все что угодно: значение и тип мы получаем, идя по цепочке к самому объекту с данными. Такой подход экономит время, но при этом имеет свои недостатки.
• Вы можете неверно написать имя переменной и получить исключение, поскольку она ни на что не ссылается, Python не выполняет такую проверку автоматически в отличие от статических языков. В главе 19 показывается способ предварительной проверки переменных.
• В сравнении с такими языками, как С, у Python скорость работы ниже. Ведь он заставляет компьютер выполнять больше работы, для того чтобы вам не пришлось выполнять ее самостоятельно.
Попробуйте сделать следующее с помощью интерактивного интерпретатора (рис. 2.4).
1. Как и раньше, присвойте значение 7 имени a. Это создаст объект-«ящик», содержащий целочисленное значение 7.
2. Выведите на экран а.
3. Присвойте имя а переменной b, заставив b прикрепиться к объекту-«ящику», содержащему значение 7.
4. Выведите b.
>>> a = 7
>>> print(a)
7
>>> b = a
>>> print(b)
7
|
|
|
|
| Рис. 2.3. Имена указывают на объекты (переменная указывает на целочисленный объект со значением 7) |
|
Рис. 2.4. Копирование имени (теперь переменная b указывает на тот же целочисленный объект) |
В Python, если нужно узнать тип какого-либо объекта (переменной или значения), можно использовать конструкцию type(объект). type() — одна из встроенных в Python функций. Чтобы проверить, указывает ли переменная на объект определенного типа, используйте конструкцию isinstance(type):
>>> type(7)
<class 'int'>
>>> type(7) == int
True
>>> isinstance(7, int)
True
Когда я упоминаю функцию, то после ее имени размещаю круглые скобки (()) и таким образом подчеркиваю, что это именно функция, а не имя переменной или что-либо еще.
Попробуем проделать это с разными значениями (58, 99.9, 'abc') и переменными (a, b):
>>> a = 7
>>> b = a
>>> type(a)
<class 'int'>
>>> type(b)
<class 'int'>
>>> type(58)
<class 'int'>
>>> type(99.9)
<class 'float'>
>>> type('abc')
<class 'str'>
Класс — это определение объекта (классы детально рассматриваются в главе 10). В Python значения терминов «класс» и «тип» примерно одинаковы.
Как вы могли заметить, при упоминании имени переменной Python ищет объект, на который она ссылается. Неявно Python выполняет большое количество действий и часто создает временные объекты, которые будут удалены спустя одну-две строки.
Снова рассмотрим пример, показанный ранее:
>>> y = 5
>>> x = 12 - y
>>> x
7
В этом фрагменте кода Python сделал следующее:
• создал целочисленный объект со значением 5;
• создал переменную у, которая указывает на этот объект;
• нарастил счетчик ссылок для объекта, содержащего значение 5;
• создал еще один целочисленный объект со значением 12;
• вычел значение объекта, на который указывает переменная у (5), из значения 12, содержащегося в анонимном объекте;
• присвоил результат (7) новому (пока еще безымянному) целочисленному объекту;
• заставил переменную х указывать на этот новый объект;
• нарастил счетчик ссылок для объекта, на который указывает переменная х;
• нашел значение объекта, на который ссылается переменная х (7), и вывел его на экран.
Когда количество ссылок на объект становится равным нулю, это означает, что ни одно имя на него больше не ссылается, поэтому хранить такой объект нет необходимости. В Python имеется сборщик мусора, который позволяет повторно использовать память, занятую уже ненужными на данный момент объектами: представьте себе, будто кто-то следит за этими полками с памятью и забирает ненужные коробки на переработку.
В нашем случае объекты со значениями 5, 12 и 7, а также переменные x и y больше не нужны. Сборщик мусора Python может или отправить их в небесный рай для объектов7, или сохранить, исходя из соображений производительности, так как небольшие целые числа используются довольно часто.
Присваивание нескольким именам
Вы можете присвоить значение сразу нескольким переменным одновременно:
>>> two = deux = zwei = 2
>>> two
2
>>> deux
2
>>> zwei
2
Переназначение имени
Поскольку имена указывают на объекты, если изменить значение, присвоенное имени, оно начнет указывать на другой объект. Счетчик ссылок старого объекта уменьшится на 1, а счетчик ссылок нового увеличится на ту же величину.
Копирование
Как вы видели на рис. 2.4, присваивание существующей переменной а новой переменной b заставит b указывать на тот же объект, что и a. Если вы выберете этикетку a или b и обратитесь к объекту, на который они указывают, вы получите одинаковый результат.
Если объект неизменяем (например, целое число), его значение нельзя изменить, поэтому по умолчанию оба имени являются доступными только для чтения. Попробуйте выполнить следующий код:
>>> x = 5
>>> x
5
>>> y = x
>>> y
5
>>> x = 29
>>> x
29
>>> y
5
Когда мы присваиваем переменную x переменной y, переменная y начинает указывать на целочисленный объект со значением 5, на который также указывает и переменная x. Далее мы изменяем переменную x так, чтобы она указывала на целочисленный объект со значением 29. Объект со значением 5, на который все еще указывает переменная y, не изменился.
В случае, когда оба имени указывают на изменяемый объект, вы можете изменить значение объекта с помощью любого имени. Если вы этого еще не знали, такая особенность может вас удивить.
Список представляет собой изменяемый массив значений (в главе 7 этот тип данных описывается более подробно). В нашем примере a и b указывают на список, содержащий три целочисленных объекта:
>>> a = [2, 4, 6]
>>> b = a
>>> a
[2, 4, 6]
>>> b
[2, 4, 6]
Эти элементы списка (a[0], a[1] и a[2]) сами по себе являются именами, указывающими на целочисленные объекты со значениями 2, 4 и 6. Список хранит элементы в заданном порядке.
Теперь давайте изменим первый элемент списка с помощью имени а и убедимся, что список b также изменился:
>>> a[0] = 99
>>> a
[99, 4, 6]
>>> b
[99, 4, 6]
Когда первый элемент списка изменяется, он больше не указывает на объект со значением 2. Теперь он указывает на объект со значением 99. Список все еще имеет тип list, но его значения (элементы списка и их порядок) можно изменить.
Выбираем хорошее имя переменной
Он говорил правильные вещи, но называл их неверными именами.
Элизабет Барретт Браунинг
Удивительно, но выбор соответствующих имен для переменных очень важен. Во многих примерах кода, которые мы успели рассмотреть, я использовал простейшие имена вроде a и x. В реальных программах вам будет нужно отслеживать гораздо больше переменных одновременно и придется балансировать между краткостью и понятностью. Например, имя num_loons можно напечатать быстрее, чем number_of_loons или gaviidae_inventory, однако они более понятны, чем имя n.
Читайте далее
Числа! Они такие увлекательные! Хотя вы, наверное, даже не предполагали насколько8. Вы увидите, как использовать Python в качестве калькулятора, а также узнаете, как кот помог создать систему счисления.
Упражнения
2.1. Присвойте целочисленное значение 99 переменной prince и выведите ее на экран.
2.2. Какого типа значение 5?
2.3. Какого типа значение 2.0?
2.4. Какого типа выражение 5+2.0?
Перед вами список зарезервированных6 слов:
Числа! Они такие увлекательные! Хотя вы, наверное, даже не предполагали насколько8. Вы увидите, как использовать Python в качестве калькулятора, а также узнаете, как кот помог создать систему счисления.
Цифра 8 похожа на снеговика!
Или на Остров забытых объектов.
async и await появились в Python 3.7.
В нашем случае объекты со значениями 5, 12 и 7, а также переменные x и y больше не нужны. Сборщик мусора Python может или отправить их в небесный рай для объектов7, или сохранить, исходя из соображений производительности, так как небольшие целые числа используются довольно часто.
