FAQ по Python в Windows

Как запустить программу на Python под Windows?

Это не всегда простой вопрос. Если вы уже знакомы с запуском программ из командной строки Windows, то все покажется очевидным; в противном случае вам может понадобиться немного больше подсказок.

Если вы не используете какую-либо интегрированную среду разработки, вам придется набирать команды Windows в так называемом «окне командной строки». Обычно вы можете создать такое окно в строке поиска, набрав cmd. Вы должны быть в состоянии распознать, когда вы запустили такое окно, потому что вы увидите «командную строку» Windows, которая обычно выглядит следующим образом:

C:\>

Буква может быть другой, и после нее может быть что-то еще, так что вы вполне можете увидеть что-то вроде:

D:\YourName\Projects\Python>

в зависимости от того, как был настроен ваш компьютер и что еще вы недавно делали с ним. Как только вы запустили такое окно, вы уже на пути к запуску программ Python.

Вы должны понимать, что ваши сценарии Python должны быть обработаны другой программой, называемой интерпретатором Python. Интерпретатор читает ваш сценарий, компилирует его в байткоды, а затем выполняет байткоды для запуска вашей программы. Итак, как организовать работу интерпретатора с вашим Python?

Во-первых, необходимо убедиться, что командное окно распознает слово «py» как команду запуска интерпретатора. Если вы открыли командное окно, попробуйте ввести команду py и нажать клавишу return:

C:\Users\YourName> py

Вы должны увидеть что-то вроде:

Python 3.6.4 (v3.6.4:d48eceb, Dec 19 2017, 06:04:45) [MSC v.1900 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>

Вы запустили интерпретатор в «интерактивном режиме». Это означает, что вы можете вводить утверждения или выражения Python в интерактивном режиме, и они будут выполняться или оцениваться, пока вы ждете. Это одна из самых сильных возможностей Python. Проверьте это, введя несколько выражений по своему выбору и посмотрев результаты:

>>> print("Hello")
Hello
>>> "Hello" * 3
'HelloHelloHello'

Многие люди используют интерактивный режим как удобный, но в то же время высокопрограммируемый калькулятор. Когда вы захотите завершить интерактивный сеанс Python, вызовите функцию exit() или удерживайте клавишу Ctrl, пока вводите Z, затем нажмите клавишу «Enter», чтобы вернуться в командную строку Windows.

Вы также можете обнаружить, что у вас есть пункт меню Пуск, например Start ‣ Programs ‣ Python 3.x ‣ Python (command line), который приводит к появлению подсказки >>> в новом окне. Если это так, окно исчезнет после вызова функции exit() или ввода символа Ctrl-Z; Windows выполняет в этом окне единственную команду «python» и закрывает его при завершении работы интерпретатора.

Теперь, когда мы знаем, что команда py распознается, вы можете передать ей свой сценарий Python. Вы должны указать абсолютный или относительный путь к сценарию Python. Допустим, ваш сценарий Python находится на рабочем столе и имеет имя hello.py, а командная строка открыта в вашем домашнем каталоге, поэтому вы видите что-то похожее на:

C:\Users\YourName>

Итак, теперь вы попросите команду py передать ваш сценарий в Python, набрав py, за которым следует путь к вашему сценарию:

C:\Users\YourName> py Desktop\hello.py
hello

Как сделать скрипты Python исполняемыми?

В Windows стандартная программа установки Python уже связывает расширение .py с типом файла (Python.File) и дает этому типу файла команду open, которая запускает интерпретатор (D:\Program Files\Python\python.exe "%1" %*). Этого достаточно, чтобы скрипты исполнялись из командной строки как „foo.py“. Если вы хотите иметь возможность выполнить сценарий, просто набрав „foo“ без расширения, вам нужно добавить .py к переменной окружения PATHEXT.

Почему Python иногда так долго запускается?

Обычно Python запускается очень быстро под Windows, но иногда появляются сообщения о том, что Python вдруг начинает долго запускаться. Это вызывает еще большее недоумение, поскольку Python прекрасно работает на других системах Windows, настроенных идентично.

Проблема может быть вызвана неправильной конфигурацией программного обеспечения для проверки вирусов на проблемной машине. Известно, что некоторые антивирусные сканеры вносят накладные расходы при запуске на два порядка, если сканер настроен на мониторинг всех чтений из файловой системы. Попробуйте проверить конфигурацию программного обеспечения для сканирования вирусов на ваших системах, чтобы убедиться, что они действительно настроены одинаково. McAfee, когда он настроен на сканирование всех операций чтения файловой системы, является особым нарушителем.

Как сделать исполняемый файл из сценария Python?

Список инструментов, которые можно использовать для создания исполняемых файлов, см. в Как создать отдельный двоичный файл из сценария Python?.

Является ли файл *.pyd тем же самым, что и DLL?

Да, файлы .pyd - это DLL, но есть несколько отличий. Если у вас есть DLL с именем foo.pyd, то у нее должна быть функция PyInit_foo(). Вы можете написать Python «import foo», и Python будет искать foo.pyd (а также foo.py, foo.pyc) и, если найдет его, попытается вызвать PyInit_foo() для его инициализации. Вы не связываете свой .exe с foo.lib, так как это заставит Windows потребовать присутствия DLL.

Обратите внимание, что путь поиска foo.pyd - это PYTHONPATH, а не тот же путь, который Windows использует для поиска foo.dll. Кроме того, foo.pyd не обязательно должен присутствовать для запуска вашей программы, тогда как если вы связали свою программу с dll, то dll необходима. Конечно, foo.pyd необходим, если вы хотите сказать import foo. В DLL связь объявляется в исходном коде с помощью __declspec(dllexport). В .pyd связь определяется в списке доступных функций.

Как встроить Python в приложение Windows?

Встраивание интерпретатора Python в приложение Windows можно описать следующим образом:

  1. Не встраивайте Python непосредственно в ваш .exe-файл. В Windows Python должен быть DLL, чтобы обрабатывать импорт модулей, которые сами являются DLL. (Это первый ключевой недокументированный факт.) Вместо этого ссылайтесь на pythonNN.dll; обычно он устанавливается в C:\Windows\System. NN - это версия Python, число, такое как «33» для Python 3.3.

    Ссылаться на Python можно двумя разными способами. Связывание во время загрузки означает связывание с pythonNN.lib, а связывание во время выполнения означает связывание с pythonNN.dll. (Общее примечание: pythonNN.lib - это так называемый «импорт lib», соответствующий pythonNN.dll. Она просто определяет символы для компоновщика).

    Связывание во время выполнения значительно упрощает параметры связей; все происходит во время выполнения. Ваш код должен загружать pythonNN.dll с помощью подпрограммы Windows LoadLibraryEx(). Код также должен использовать процедуры доступа и данные в pythonNN.dll (то есть, C API Python), используя указатели, полученные с помощью процедуры Windows GetProcAddress(). Макросы могут сделать использование этих указателей прозрачным для любого кода на C, который вызывает процедуры в C API Python.

  2. Если вы используете SWIG, легко создать «модуль расширения» Python, который сделает данные и методы приложения доступными для Python. SWIG выполнит за вас практически все сложные детали. В результате вы получите код на языке C, который вы подключите в ваш .exe файл (!) Вам _не_ нужно создавать DLL файл, и это также упрощает подключение.

  3. SWIG создаст функцию init (функцию на языке C), имя которой зависит от имени модуля расширения. Например, если имя модуля - leo, функция init будет называться initleo(). Если вы используете теневые классы SWIG, как и должно быть, функция init будет называться initleoc(). Это инициализирует скрытый вспомогательный класс, используемый теневым классом.

    Причина, по которой вы можете подключить код на языке Си в шаге 2 к вашему .exe-файлу, заключается в том, что вызов функции инициализации эквивалентен импорту модуля в Python! (Это второй ключевой недокументированный факт).

  4. Короче говоря, вы можете использовать следующий код для инициализации интерпретатора Python с вашим модулем расширения.

    #include "python.h"
    ...
    Py_Initialize();  // Initialize Python.
    initmyAppc();  // Initialize (import) the helper class.
    PyRun_SimpleString("import myApp");  // Import the shadow class.
    
  5. Есть две проблемы с C API Python, которые станут очевидными, если вы используете компилятор, отличный от MSVC, который использовался для сборки pythonNN.dll.

    Проблема 1: Так называемые функции «очень высокого уровня», принимающие аргументы FILE *, не будут работать в среде с несколькими компиляторами, поскольку понятие struct FILE в каждом компиляторе будет отличаться. С точки зрения реализации это функции очень _низкого_ уровня.

    Проблема 2: SWIG генерирует следующий код при создании оберток для функций void:

    Py_INCREF(Py_None);
    _resultobj = Py_None;
    return _resultobj;
    

    Увы, Py_None - это макрос, который расширяется до ссылки на сложную структуру данных под названием _Py_NoneStruct внутри pythonNN.dll. Опять же, этот код будет неудачным в среде с несколькими компиляторами. Замените этот код на:

    return Py_BuildValue("");
    

    Возможно, можно использовать команду SWIG %typemap для автоматического внесения изменений, хотя я не смог заставить ее работать (я полный новичок в SWIG).

  6. Использование сценария оболочки Python для размещения окна интерпретатора Python внутри вашего приложения Windows - не самая лучшая идея; полученное окно будет независимым от оконной системы вашего приложения. Скорее, вы (или класс wxPythonWindow) должны создать «родное» окно интерпретатора. Это окно легко подключить к интерпретатору Python. Вы можете перенаправить ввод-вывод Python на _любой_ объект, поддерживающий чтение и запись, поэтому все, что вам нужно, это объект Python (определенный в вашем модуле расширения), содержащий методы read() и write().

Как сделать так, чтобы редакторы не вставляли вкладки в исходный текст Python?

FAQ не рекомендует использовать табуляцию, а руководство по стилю Python, PEP 8, рекомендует использовать 4 пробела для распределенного кода Python; это также значение по умолчанию в Emacs python-mode.

В любом редакторе смешивать табуляцию и пробелы - плохая идея. MSVC не отличается в этом отношении, и легко настраивается на использование пробелов: Возьмите Tools ‣ Options ‣ Tabs, и для типа файла «Default» установите «Tab size» и «Indent size» на 4, и выберите радиокнопку «Insert spaces».

Python выдает сообщение IndentationError или TabError, если смешанные табуляции и пробелы вызывают проблемы при выводе пробельных символов. Вы также можете запустить модуль tabnanny для проверки дерева каталогов в пакетном режиме.

Как проверить нажатие клавиши без блокировки?

Используйте модуль msvcrt. Это стандартный модуль расширения, специфичный для Windows. Он определяет функцию kbhit(), которая проверяет наличие удара по клавиатуре, и getch(), которая получает один символ без эха.

Вернуться на верх