Вместо анализа и вычисления выражений вручную калькулятор использует функции eval и exec для вызова парсера и интерпретатора Python во время исполнения. По существу, калькулятор выполняет встроенный программный код Python из программы Python. Это возможно благодаря тому, что среда разработки Python (парсер и компилятор байт-кода) всегда являются частью систем, использующих Python. Поскольку различия между средой разработки и средой выполнения отсутствуют, программы на языке Python имеют возможность использовать парсер Python.
В результате всё вычисление выражения заменяется одним вызовом eval или exec. В более широком смысле это мощный прием, о котором следует помнить: сам язык Python может заменить много небольших специальных языков. Помимо того что сокращается время разработки, клиентам приходится учить лишь один язык, который может быть достаточно прост, чтобы конечный пользователь мог программировать на нем.
Кроме того, Python может приобретать особенности любого приложения. Если интерфейс языка требует специфических для приложения расширений, просто добавьте классы Python или экспортируйте API для использования во встроенном программном коде Python в качестве расширения на языке C. В результате интерпретации программного кода Python со специфическими для приложения расширениями необходимость в индивидуальных парсерах почти полностью отпадает.
Есть также важное дополнительное преимущество такого подхода: у встроенного программного кода Python есть доступ ко всем средствам и возможностям мощного развитого языка программирования. Он может пользоваться списками, функциями, классами, внешними модулями и даже такими крупными инструментами Python, как библиотека tkinter, хранилища shelve, потоки выполнения, сетевые сокеты и средства получения веб-страниц. Вам могут понадобиться годы, чтобы обеспечить такие функции в специальном парсере языка. Можете поинтересоваться у Гвидо.
Обратите внимание, что внутри циклов параметры передаются lambda- выражениям как ар гумен ты по умол ча нию. Вспомните, как в главе 7 говорилось, что ссылки внутри lambda-выражений (или внутри вложенных инструкций def) на имена в объемлющей области видимости разыменовываются в момент вызова вложенной функции, а не в момент ее создания. Когда позднее сгенерированная функция будет вызвана, ссылки внутри lambda-выражений будут отражать последние значения, полученные во внешней области видимости, которые могут не совпадать со значениями, имевшимися на момент выполнения lambda-выражений. Значения по умолчанию, напротив, вычисляются в момент создания функций и поэтому позволяют сохранять текущие значения переменных цикла. Без аргументов по умолчанию все кнопки отражали бы значение, полученное в последней итерации цикла.
Использованная литература:
Марк Лутц — Программирование на Python, 4-е издание, II том, 2011