- •Об авторе
- •О группе редакторов
- •Предисловие
- •Введение
- •Как использовать эту книгу
- •Загрузка исходного кода CPython
- •Что в исходном коде?
- •Настройка среды разработки
- •IDE или редактор?
- •Настройка Visual Studio
- •Настройка Visual Studio Code
- •Настройка Vim
- •Выводы
- •Компиляция CPython
- •Компиляция CPython на macOS
- •Компиляция CPython на Linux
- •Установка специализированной версии
- •Знакомство с Make
- •Make-цели CPython
- •Компиляция CPython на Windows
- •Профильная оптимизация
- •Выводы
- •Грамматика и язык Python
- •Спецификация языка Python
- •Генератор парсеров
- •Повторное генерирование грамматики
- •Выводы
- •Конфигурация и ввод
- •Конфигурация состояния
- •Структура данных конфигурации среды выполнения
- •Конфигурация сборки
- •Сборка модуля из входных данных
- •Выводы
- •Генерирование конкретного синтаксического дерева
- •Парсер/токенизатор CPython
- •Абстрактные синтаксические деревья
- •Важные термины
- •Пример: добавление оператора «почти равно»
- •Выводы
- •Компилятор
- •Исходные файлы
- •Важные термины
- •Создание экземпляра компилятора
- •Флаги будущей функциональности и флаги компилятора
- •Таблицы символических имен
- •Основная компиляция
- •Ассемблер
- •Создание объекта кода
- •Использование Instaviz для вывода объекта кода
- •Пример: реализация оператора «почти равно»
- •Выводы
- •Цикл вычисления
- •Исходные файлы
- •Важные термины
- •Построение состояния потока
- •Построение объектов кадров
- •Выполнение кадра
- •Стек значений
- •Пример: добавление элемента в список
- •Выводы
- •Управление памятью
- •Выделение памяти в C
- •Проектирование системы управления памятью Python
- •Аллокаторы памяти CPython
- •Область выделения объектной памяти и PyMem
- •Область выделения сырой памяти
- •Нестандартные области выделения памяти
- •Санитайзеры выделенной памяти
- •Арена памяти PyArena
- •Подсчет ссылок
- •Сборка мусора
- •Выводы
- •Параллелизм и конкурентность
- •Модели параллелизма и конкурентности
- •Структура процесса
- •Многопроцессорный параллелизм
- •Многопоточность
- •Асинхронное программирование
- •Генераторы
- •Сопрограммы
- •Асинхронные генераторы
- •Субинтерпретаторы
- •Выводы
- •Объекты и типы
- •Примеры этой главы
- •Встроенные типы
- •Типы объектов
- •Тип type
- •Типы bool и long
- •Тип строки Юникода
- •Словари
- •Выводы
- •Стандартная библиотека
- •Модули Python
- •Модули Python и C
- •Набор тестов
- •Запуск набора тестов в Windows
- •Запуск набора тестов в Linux или macOS
- •Флаги тестирования
- •Запуск конкретных тестов
- •Модули тестирования
- •Вспомогательные средства тестирования
- •Выводы
- •Отладка
- •Обработчик сбоев
- •Компиляция поддержки отладки
- •LLDB для macOS
- •Отладчик Visual Studio
- •Отладчик CLion
- •Выводы
- •Бенчмаркинг, профилирование и трассировка
- •Использование timeit для микробенчмарка
- •Использование набора тестов производительности Python
- •Профилирование кода Python с использованием cProfile
- •Выводы
- •Что дальше?
- •Создание расширений C для CPython
- •Улучшение приложений Python
- •Участие в проекте CPython
- •Дальнейшее обучение
- •Препроцессор C
- •Базовый синтаксис C
- •Выводы
- •Благодарности
336 Что дальше?
zz Во многих функциях и модулях стандартной библиотеки отсутствуют модульные тесты. Напишите тесты и отправьте их в проект.
zz Многие функции стандартной библиотеки не имеют актуальной документации. Обновите документацию и отправьте изменения.
ДАЛЬНЕЙШЕЕ ОБУЧЕНИЕ
Одна из самых сильных сторон Python — сообщество. Знаете людей, изучающих Python? Помогите им! Если вы хотите убедиться в том, что вы действительно усвоили какую-то концепцию, попробуйте объяснить ее другим.
Продолжайте свое путешествие в мир Python, посетив наш сайт realpython.com.
Еженедельные советы для Python-разработчиков
Хотите каждую неделю получать порцию рекомендаций, которые улучшают производительность и оптимизируют ваш рабочий процесс? Хорошие новости: специально для таких Python-разработчиков, как вы, мы ведем еженедельную бесплатную рассылку по электронной почте.
Рассылка не сводится к материалам типа «вот вам список популярных статей». Мы стараемся делиться как минимум одной оригинальной мыслью в неделю в формате очерка (краткого).
Если вас это заинтересует, перейдите по адресу realpython.com/newsletter и введите адрес электронной почты в форме регистрации. До скорой встречи!
Библиотека видеокурсов Real Python
Большая (и постоянно растущая) подборка учебников Python и учебных материалов поможет вам достичь уровня всесторонне развитого питониста. Новые материалы публикуются еженедельно, и вы всегда найдете что-то интересное для повышения вашей квалификации.
zz Осваивайте практически значимые навыки программирования на языке Python: созданием, отбором и контролем наших учебных материалов занимается целое сообщество опытных разработчиков. На сайте Real Python вы найдете ресурсы, заслуживающие доверия, которые пригодятся вам при совершенствовании мастерства программирования на Python.
Книги для программистов: https://t.me/booksforits
Дальнейшее обучение 337
zz Знакомьтесь с другими питонистами: присоединяйтесь к чату сообщества Real Python и еженедельным Q&A сессиям, чтобы познакомиться с командой Real Python и с другими неофитами. Получайте ответы на свои вопросы, относящиеся к Python, обсуждайте вопросы программирования и построения карьеры или просто проводите с нами время у этого виртуального кофейного автомата.
zz Пройдите интерактивные тесты и траектории обучения: реальные задачи по кодированию, интерактивные тесты и программы обучения, ориентированные на получение необходимых навыков, позволят вам оценить ваш текущий уровень и потренироваться в применении новых знаний.
zz Отслеживайте ход обучения: помечайте уроки как завершенные или «в процессе», занимайтесь в наиболее подходящем для вас темпе. Создавайте закладки на самых интересных уроках и просматривайте их позднее, чтобы запомнить надолго.
zz Получайте сертификаты об окончании курсов: по окончании каждого курса вы получаете сертификат, который можно предъявить (в электронном или печатном виде). Включайте сертификаты в свой проектный портфель, резюме на LinkedIn или на других веб-сайтах, чтобы показать миру, что вы продвинутый питонист.
zz Идите в ногу со временем: поддерживайте свои рабочие навыки на должном уровне и не отставайте от технологических новинок. Мы постоянно выпускаем новые учебные материалы только для зарегистрированных участников, а также регулярно обновляем контент.
За информацией о доступных курсах обращайтесь на realpython.com/courses.
Книги для программистов: https://t.me/booksforits
Приложение.
Введение в C для Pythonпрограммистов
Приложение предназначено для опытных Python-разработчиков, желающих освоить азы языка C и научиться пользоваться им, работая с исходным кодом CPython. Предполагается, что читатель понимает синтаксис Python хотя бы на среднем уровне.
Язык C не особенно сложен, и то, как он применяется в CPython, можно свести к небольшому набору синтаксических правил. Вы довольно быстро научитесь понимать код, однако умение писать эффективные программы на C приходит намного позднее. Данное руководство преследует лишь первую цель.
Начнем с первого отличия между Python и C, с которым вы сталкиваетесь практически немедленно, — препроцессора C.
ПРЕПРОЦЕССОР C
Препроцессор обрабатывает исходные файлы до того, как они будут обработаны компилятором. Он обладает весьма ограниченными возможностями, но эти возможности приносят огромную пользу при построении программ на C.
Препроцессор создает новый файл, который, собственно, и будет реально обрабатываться компилятором. Все команды препроцессора размещаются в начале строки, а первым непробельным символом в них является знак #.
Книги для программистов: https://t.me/booksforits
Препроцессор C 339
Главная цель препроцессора — замена текста в исходном файле, но он также может выполнять простейшие условные конструкции при помощи #if и других операторов.
Начнем с самой распространенной директивы препроцессора: #include.
#include
#include подставляет содержимое одного файла в текущий исходный файл. В директиве #include нет ничего сложного: она читает файл из файловой системы, обрабатывает его препроцессором и помещает результаты в выходной файл. Это происходит рекурсивно для каждой директивы #include. Например, если заглянуть в файл Modules/_multiprocessing/semaphore.c, то в начале этого файла обнаруживается следующая строка:
#include "multiprocessing.h"
Она приказывает препроцессору взять все содержимое multiprocessing.h и подставить его в выходной файл в соответствующей позиции.
Команда #include существует в двух разных формах. В одной имя включаемого файла заключается в двойные кавычки (""), а в другой — в угловые скобки (<>). Эти формы различаются тем, по какому пути выполняется поиск файла в файловой системе.
Если имя файла заключено в угловые скобки <>, то препроцессор ограничивается системными файлами. Если же название файла в кавычках, препроцессор сначала ищет файл в локальном каталоге и только потом переходит к системным каталогам.
#define
Директива #define позволяет выполнять простую замену текста, а также сочетается с директивами #if, о которых будет рассказано ниже.
На простейшем уровне #define определяет новое символическое имя, которое заменяется текстовой строкой в выводе препроцессора.
Так, в файле semaphore.c присутствует следующая строка:
#define SEM_FAILED NULL
Книги для программистов: https://t.me/booksforits
340 Приложение. Введение в C для Python-программистов
Она приказывает препроцессору заменить каждый экземпляр SEM_FAILED ниже этой точки литеральной строкой NULL, прежде чем код будет передан компилятору.
Директивы #define также могут получать параметры, как в следующей версии SEM_CREATE для Windows:
#define SEM_CREATE(name, val, max) CreateSemaphore(NULL, val, max, NULL)
В данном случае препроцессор ожидает, что SEM_CREATE() будет выглядеть как вызов функции и получит три параметра. Обычно подстановки такого рода называются макросами. Текст трех параметров напрямую подставляется в выходной код.
Например, в строке 460 файла semaphore.c макрос SEM_CREATE используется следующим образом:
handle = SEM_CREATE(name, value, max);
При компиляции на Windows происходит расширение макроса, в результате чего строка будет выглядеть так:
handle = CreateSemaphore(NULL, value, max, NULL);
Как будет показано ниже, этот макрос по-разному определяется в разных операционных системах.
#undef
Директива стирает все предшествующие определения препроцессора из #define. Это позволяет ограничить воздействие #define частью файла.
#if
Препроцессор также поддерживает условные конструкции, которые позволяют включать или исключать фрагменты текста в зависимости от определенных условий. Условные команды закрываются директивой #endif. Для более точной настройки можно также использовать #elif и #else.
В исходном коде CPython встречаются три основные разновидности #if:
Книги для программистов: https://t.me/booksforits