Точка входа программы
Текст программы начинается с инструкции #include, которая позволяет включить в программу заголовочный файл WINDOWS.H:
WINDOWS.H включает в себя много других заголовочных файлов, содержащих объявления функций Windows, структур Windows, новые типы данных и числовые константы.
За инструкцией #includeследует объявлениеWndProc:
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
Это объявление в начале программы необходимо потому, что в тексте функции WinMainимеются ссылки на функциюWndProc.
В программе на языке С, написанной для традиционной среды, точкой входа является функция main. С этого места программа начинает выполняться. (Фактически функция main является точкой входа в ту часть программы, которая пишется программистом. Обычно компилятор С должен вставить некоторый стартовый код в исполняемый файл. Этот код и вызывает функциюmain.) Точкой входа программы для Windows является функцияWinMain.WinMain всегда определяется следующим образом:
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
Эта функция использует последовательность вызовов WINAPI и, по своему завершению, возвращает операционной системе Windows целое. Функция называется WinMain. В ней есть четыре параметра.
Параметр hInstanceназывается описателем экземпляра (instance handle). Это уникальное число, идентифицирующее программу, когда она работает под Windows. Может так случиться, что пользователь запустит под Windows несколько копий одной и той же программы. Каждая копия называется “экземпляром” и у каждой свое значениеhInstance. Описатель экземпляра можно сравнить с “идентификатором задачи” или “идентификатором процесса” — обычными терминами многозадачных операционных систем.
Параметр hPrevInstance—всегда равен NULL.
Параметр szCmdLine— это указатель на оканчивающуюся нулем строку, в которой содержатся любые параметры, переданные в программу из командной строки. Вы можете запустить программу для Windows с параметром командной строки, вставив этот параметр после имени программы в командной строке MS-DOS или указать имя программы и параметр в окне диалога Run, которое вызывается из меню Start.
Параметр iCmdShow— число, показывающее, каким должно быть выведено на экран окно в начальный момент. Это число задается при запуске программы другой программой. Программисты достаточно редко обращаются к этому числу, но при необходимости такая возможность существует. В большинстве случаев число равно 1 или 7. Но лучше не думать об этом значении как о единице или как о семерке. Лучше думайте о них как об идентификаторе SW_SHOWNORMAL (заданном в заголовочных файлах Windows равным 1) или идентификаторе SW_SHOWMINNOACTIVE (заданном равным 7). Префикс SW в этих идентификаторах означает “показать окно” (show window). Параметр показывает, необходимо ли запущенную пользователем программу выводить на экран в виде окна нормального размера или окно должно быть изначально свернутым.
Оконная процедура
Вы, несомненно, уже привыкли к мысли, что программа делает вызовы операционной системы. Таким образом, например, программа открывает файл на жестком диске. Но возможно и обратное, когда операционная система вызывает программу. Это непривычно, тем не менее, это суть объектно-ориентированной архитектуры Windows. При программировании для Windows вы фактически занимаетесь одним из видов объектно-ориентированного программирования.
У каждого окна, создаваемого программой, имеется соответствующая оконная процедура. Windows посылает сообщение окну путем вызова оконной процедуры, на основе этого сообщения окно совершает какие-то действия и затем возвращает управление Windows. “Windows посылает программе сообщение” — имеется в виду, что Windows вызывает функцию внутри программы. Параметры этой функции описывают параметры сообщения. Эта функция, находящаяся в вашей программе для Windows, называется оконной процедурой (window procedure). Все это называется ”Архитектура, управляемая событиями”.
Более точно, окно всегда создается на основе”класса окна”. Класс окна определяет оконную процедуру,обрабатывающую поступающие окну сообщения. Использование класса окна позволяет создавать множество окон на основе одного и того же класса окна и, следовательно, использовать одну и ту же оконную процедуру.Например, все кнопки во всех программах дляWindows созданы на основе одного и того же класса окна. Этот класс связан с оконной процедурой(расположенной в динамически подключаемой библиотекеWindows), которая управляет процессом передачи сообщений всем кнопкам всех окон.В объектно-ориентированном программировании любой”объект” несет в себе сочетание кода и данных. Окно— это объект. Код— это оконная процедура. Данные— это информация, хранимая оконной процедурой, и информация,хранимая системойWindows для каждого окна и каждого класса окна, которые имеются в системе.Оконная процедура обрабатывает сообщения, поступающие окну. Очень часто эти сообщения передают окну информацию о том, что пользователь осуществил ввод с помощью клавиатуры или мыши. Таким образом,например, кнопки”узнают” о том, что они нажаты. Другие сообщения говорят окну о том, что необходимо изменить размер окна или о том, что поверхность окна необходимо перерисовать.Когда программа дляWindows начинает выполняться, Windows строит для программы очередь сообщений(messagequeue). В этой очереди хранятся сообщения для любых типов окон, которые могли бы быть созданы программой.Небольшая часть программы, которая называется циклом обработки сообщений(message loop), выбирает эти сообщения из очереди и переправляет их соответствующей оконной процедуре. Другие сообщения отправляются непосредственно оконной процедуре минуя очередь сообщений.
Точка входа
В программах, написанных на Python часто можно увидеть такую конструкцию:
if __name__ == "__main__":
Это точка входа — место, с которого начинает выполняться ваша программа. Но какие еще значения может принимать переменная __name__ ? Зачем вообще нужна эта проверка?
Переменная __name__
Для начала, попробуем провести несколько экспериментов. Создадим папку с тремя файлами: my_module.py , calculations.py и processing.py . А теперь выведем на экран переменные __name__ каждого из этих файлов. В каждом случае результат будет одинаковым.
>>> __name__ '__main__' А теперь попробуем импортировать модули, и снова проверить значение их переменных `__name__`. ```pycon >>> import my_module >>> import calculations >>> my_module.__name__ my_module >>> calculations.__name__ calculations >>> .dir() [. '__name__', . 'calculations', 'my_module']
Как видите, переменная __name__ теперь содержит название файла импортированного модуля. Функция dir() в нашем случае возвращает глобальное пространство имен. В конце списка притаились те самые имена импортированных модулей. Теперь мы сможем обращаться к их содержимому через эти названия.
Точка входа
Давайте разберем работу типичной точки входа на примере файла processing.py .
import calculations import my_module def main(): while True: inp = input("Insert value:") converted = calculations.convert(inp) transformed = calculations.transform(converted) print(my_module.output(transformed)) if __name__ == "__main__": main()
Сначала интерпретатор импортирует модули, затем определяет функцию main() , и доходит до блока if __name__ == ‘__main__’: . Если пользователь непосредственно запустил файл processing.py , условие будет удовлетворено, и начнется выполнение функции main() . Пользователь сможет ввести какую-то строку в консоль, она будет обработана функциями из модулей calculations и my_module , а затем выведена на экран. Цикл будет повторяться, пока пользователь не завершит программу.
Но представьте себе, что мы решили сделать более сложную программу, которая использует те же функции. Чтобы не переписывать тот же самый код, мы импортировали processing.py . Если бы мы не проверяли значение переменной __name__ , функция main() запустилась бы при импорте. Программа застряла бы в одном бесконечном цикле while , а интерпретатор никогда не дошел бы до кода нашей новой программы.
>>> import processing Insert value:
Это было бы крайне нежелательно. Поэтому мы и проверяем содержимое переменной __name__ перед запуском функции main() . Поскольку при импорте ее содержимое меняется на название модуля – processing , то проверка не будет пройдена, и main() не запустится. Зато мы сможем использовать любые объекты импортированного модуля:
import processing mode = input('Mode:') if mode == 'standard': processing.main() else print(processing.my_module.output(input()))
Заключение
С точки входа начинается выполнение программы. Содержимое блока if __name__ == ‘__main__’: не выполняется, если файл импортирован, а не запущен напрямую. Это позволяет разместить в нем код, который помешал бы импорту содержимого модуля, но нужен при непосредственном доступе. Использование этой конструкции — хорошая практика, которая поможет избежать проблем при импорте вашего модуля.
Практический Python для начинающих
Станьте junior Python программистом за 7 месяцев
При подготовке материала использовались источники:
https://studfile.net/preview/1825564/page:4/
https://pylot.me/article/38-tochka-vhoda/