01 / ПРОБЛЕМА
Код меняется постоянно. Почему отладчик показывает только настоящее?
numbers = []
for i in range(5):
numbers.append(i * i)
result = sum(numbers)numbers = [0, 1, 4, 9, 16] result = 30Но программа не появилась в этом состоянии мгновенно.
- T+00
[] - T+01
[0] - T+02
[0, 1] - T+03
[0, 1, 4] - T+05
[0, 1, 4, 9, 16]
Каждая строка постепенно изменяла состояние программы. Обычно эту историю приходится восстанавливать самому — ставить breakpoints, перезапускать код и добавлять print().
02 / ИСТОРИЯ ИСПОЛНЕНИЯ
Вернитесь к любому моменту выполнения
После запуска программы её прошлое не исчезает.
Перемещайтесь назад и вперёд и наблюдайте состояние программы в выбранный момент — без повторного запуска.
Код программы
numbers = [] for i in range(5): numbers.append(i * i) result = sum(numbers)Попробуйте нажать «Назад»: список numbers вернётся к предыдущему состоянию без перезапуска программы.
Что находилось в списке пять шагов назад?
Какое значение было перед вызовом функции?
Что происходило непосредственно перед ошибкой?
03 / АЛЬТЕРНАТИВЫ
Исследуйте не только прошлое, но и возможное будущее

Возвращайтесь к предыдущей точке выполнения и исследуйте альтернативное продолжение. Сравнивайте истории и наблюдайте, как небольшое изменение влияет на дальнейшее поведение.
Одна программа может иметь несколько историй исполнения.
04 / ОШИБКИ
Ошибка — это не только последняя строка traceback
Traceback показывает место, где проблема проявилась.
История исполнения помогает понять, где она возникла.
Неверное значение могло появиться десятки операций назад.
Объект мог быть изменён не там, где вы ожидали.
Функция могла получить данные, уже испорченные предыдущим кодом.
05 / ПРАКТИКА
Полезно не только для поиска ошибок
Когда вы изучаете Python
Циклы, функции, области видимости, изменяемые объекты и вложенные вызовы проще понимать, когда их можно наблюдать во времени.
Когда вы разбираетесь в чужом коде
Сначала посмотрите, какие значения появляются, куда передаются и какие функции вызываются. Затем разбирайтесь в реализации.
Когда программа просто делает не то
Найдите первый момент, когда реальное состояние начало отличаться от ожидаемого — без десятков print() и перезапусков.

EXECUTION HAS A PAST
Попробуйте посмотреть на Python-программу по-другому
Исследуйте выполнение программы, а не только её результат.
Открыть PyChronicle