- •§0.1. Базовые знания
- •§0.2. Где достать интерпретатор языка Питон?
- •§0.3. Установка интерпретатора языка Питон в unix
- •§0.3.1. Установка/обновление Питона из грт-пакета
- •§0.3.2. Установка Питона из исходного кода
- •§0.4. Установка Питона в ос Windows
- •§0.5. Запуск программ, написанных на Питоне
- •§0.6. Среда разработки
- •§1.1. Алгоритмы и программы
- •§1.2. Языки программирования и уровни абстракции
- •Глава 1. Базовые понятия
- •§1.3. Формальные и естественные языки
- •§1.4. Интерпретаторы и компиляторы
- •§1.5. Первая программа
- •§1.6. Что такое отладка?
- •§1.6.1. Синтаксические ошибки (syntax errors)
- •§1.6.2. Ошибки выполнения (runtime errors)
- •§1.6.3. Семантические ошибки (semantic errors)
- •§1.6.4. Процесс отладки
- •Глава 2. Переменные, операции и выражения
- •§2.1. Значения и типы
- •§2.2. Преобразование типов
- •§2.3. Переменные
- •§2.4. Имена переменных и ключевые слова
- •§2.5. Выражения
- •§2.6. Выполнение выражений
- •§2.7. Операторы и операнды
- •§2.8. Порядок операций
- •§2.9. Простейшие операции над строками
- •§2.10. Композиция
- •Глава 3. Функции §3.1. Подпрограммы
- •§3.2. Вызовы функций
- •§3.3. Справочная система
- •§3.4. Импорт модулей и математические функции
- •§3.5. Композиция
- •§3.6. Создание функций
- •§3.7. Параметры и аргументы
- •§3.8. Локальные переменные
- •§3.9. Поток выполнения
- •§3.10. Стековые диаграммы
- •§3.11. Функции, возвращающие результат
- •Глава 4. Компьютерная графика
- •Глава 5. Логические выражения, условия и рекурсия §5.1. Комментарии в программах
- •§5.2. Простые логические выражения и логический тип данных
- •§5.3. Логические операторы
- •§5.4. Выполнение по условию и «пустота»
- •§5.5. Ввод данных с клавиатуры
- •§5.6. Альтернативные ветки программы (Chained conditionals)
- •§5.7. Пустые блоки
- •§5.8. Вложенные условные операторы (Nested conditionals)
- •§5.9. Рекурсия
- •§5.10. Стековые диаграммы рекурсивных вызовов
- •§5.11. Максимальная глубина рекурсии
- •§5.12. Числа Фибоначчи
- •Глава 6. Циклы
- •§6.1. Оператор цикла while
- •§6.2. Счетчики
- •§6.3. Бесконечные циклы
- •§6.4. Альтернативная ветка цикла while
- •§6.5. Табулирование функций
- •§6.6. Специальные и экранируемые символы
- •§6.7. Числа Фибоначчи и оператор цикла while
- •§6.8. Вложенные операторы цикла и двумерные таблицы
- •§6.9. Классификация операторов цикла
- •§6.10. Управляющие структуры
- •Глава 7. Строки
- •§7.1. Оператор индексирования
- •§7.2. Длина строки и отрицательные индексы
- •§7.3. Перебор и цикл for
- •§7.4. Срезы строк
- •§7.5. Сравнение строк
- •§7.6. Строки нельзя изменить
- •§7.7. Функция find
- •§7.8. Циклы и счётчики
- •§7.9. Модуль string
- •§7.10. Классификация символов
- •§10.2. Операции над словарями
- •§10.3. Методы словарей
- •§10.4. Использование псевдонимов и копирование
- •§10.5. Разряженные матрицы
- •§10.6. Подсказки
- •§10.7. Тип «длинное целое число»
- •§10.8. Подсчет букв
§3.9. Поток выполнения
Как уже было сказано, с появлением функций (и процедур) программы перестали быть линейными, в связи с этим возникло понятие потока выполнения- последовательности выполнения инструкций, составляющих программу.
Выполнение программы, написанной на Питоне всегда начинается с первого выражения, а последующие выражения выполняются один за другим сверху вниз. Причем, определения функций никак не влияют на поток выполнения, т.к. тело любой функции не выполняется до тех пор, пока не будет вызвана соответствующая функция.
Когда интерпретатор, разбирая исходный код, доходит до вызова функции, он, вычислив значения аргументов, начинает выполнять тело вызываемой функции и только после ее завершения переходит к разбору следующей инструкции.
Все довольно просто, хотя проследить поток выполнения в сложных программах зачастую оказывается задачей нетривиальной, т.к. в теле любой функции может быть вызвана другая функция, которая тоже может в своем теле содержать вызовы функций и т.д. Тем не менее, интерпретатор Питона помнит откуда была вызвана каждая функция, и рано или поздно, если походу выполнения не возникнет никаких исключений, он вернется к исходному вызову, чтобы перейти к следующей инструкции.
Итак, представим, что у нас имеется три функции: fl (), f2 () и f3 (). Причем они вызывают друг друга таким образом:
def fl () : |
|
"fl() begins" |
|
"Hello world!" |
|
"fl() ends" |
|
def f2 () : |
|
"f2() begins" |
|
fl() |
|
43
Ревизия: 170
Функции
"f2() ends" |
|
def f3 () : |
|
"f3() begins" |
|
f2() |
|
"f3() ends" |
|
print "Main program begins" |
|
f3() |
|
print "Main program ends" |
|
Для того, чтобы проследить последовательность выполнения операций, мы добавили команды которые будут сигнализировать, когда начинается и заканчивается каждая функция. Итак, запустим программу и посмотрим, что у нас получилось:
$ python ргодб |
РУ |
|||
Main |
program |
begins |
||
f3() |
begins |
|
|
|
f2() |
begins |
|
|
|
fl() |
begins |
|
|
|
Hellc |
э world! |
|
|
|
fl() |
ends |
|
|
|
f2() |
ends |
|
|
|
f3() |
ends |
|
|
|
Main |
program |
ends |
||
Разберем полученный результат. Как уже было сказано, определения функций никак не влияют на выполнение основной программы. Исключением является случай, когда интерпретатор сталкивается с синтаксической ошибкой в теле функции: даже если еще не настало время ее выполнения, он выведет сообщение об ошибке и завершит работу.
Основная программа, начинается с вывода сообщения о своем начале, затем вызывается функция f 3 (), которая, «представившись» вызывает, функцию f 2 (). Та, в свою очередь, поступает аналогичным образом, вызывая f 1 (). f 1 () тоже выводит сообщение о своем начале, затем тестовое приветствие миру и сообщение о своем завершении. Поток выполнения возвращается в тело функции f2 () к тому месту, откуда была вызвана fl(), после чего выполняется следующая инструкция, выводящая сообщение о том, что функция f 2 () завершает свою работу. Как вы уже догадались, поток выполнения возвращается в тело функции f 3 (), а после ее завершения - в основную программу.
