Заметка
Доступ к этой странице требует авторизации. Вы можете попробовать войти в систему или изменить каталог.
Доступ к этой странице требует авторизации. Вы можете попробовать сменить директорию.
Большинство обычных отладчиков Python поддерживают только отладку кода Python, но это распространенная практика для разработчиков использовать Python с C или C++. Некоторые сценарии, использующие смешанный код, — это приложения, требующие высокой производительности или возможности непосредственного вызова API платформы, часто кодируются в Python и C++.
Visual Studio предоставляет интегрированную, одновременную отладку в смешанном режиме для кода Python и собственного кода C/C++. Поддержка доступна при выборе параметра собственных средств разработки Python для рабочей нагрузки разработки Python в установщике Visual Studio:
В этой статье вы узнаете, как работать со следующими функциями отладки в смешанном режиме:
- Объединенные стеки вызовов
- Шаг между Python и машинным кодом
- Точки останова в обоих типах кода
- Просмотр представлений объектов Python в естественных кадрах и наоборот
- Отладка в контексте проекта Python или проекта C++
Предпосылки
Visual Studio 2017 и более поздних версий. Отладка в смешанном режиме недоступна с помощью средств Python для Visual Studio 1.x в Visual Studio 2015 и более ранних версиях.
Visual Studio, установленное с поддержкой задач Python. Дополнительные сведения см. в статье "Установка поддержки Python в Visual Studio".
Включение отладки в смешанном режиме в проекте Python
Ниже описано, как включить отладку в смешанном режиме в проекте Python:
В обозревателе решений щелкните правой кнопкой мыши проект Python и выберите "Свойства".
В области "Свойства" выберите вкладку "Отладка ", а затем выберите параметр отладки>"Включить отладку машинного кода ":
Этот параметр включает смешанный режим для всех сеансов отладки.
Подсказка
При включении отладки нативного кода окно вывода Python может закрыться сразу после завершения программы, не показывая запрос Нажмите любую клавишу, чтобы продолжить. Чтобы принудить приостановку и запрос после включения отладки нативного кода, добавьте аргумент
-iв поле Запуск>Аргументы интерпретатора на вкладке Отладка. Этот аргумент переводит интерпретатор Python в интерактивный режим после выполнения кода. Программа ожидает, когда вы выберете Ctrl+Z+ВВОД, чтобы закрыть окно.Нажмите кнопку"Сохранить>" (или CTRL+S), чтобы сохранить изменения свойств.
Чтобы подключить отладчик смешанного режима к существующему процессу, выберите "Подключить отладку>к процессу". Откроется диалоговое окно.
В диалоговом окне "Присоединение к процессу" выберите соответствующий процесс из списка.
Чтобы подключиться к полю, используйте параметр "Выбрать ", чтобы открыть диалоговое окно "Выбор типа кода ".
В диалоговом окне "Выбор типа кода " выберите параметр "Отладка этих типов кода ".
В списке установите флажок Python (собственный) и нажмите кнопку ОК:
Нажмите кнопку "Присоединить" , чтобы запустить отладчик.
Параметры типа кода являются постоянными. Если вы хотите отключить отладку в смешанном режиме и присоединиться к другому процессу позже, снимите флажок типа кода Python (независимый) и установите флажок типа кода Независимый.
Вы можете выбрать другие типы кода в дополнение к параметру Native или вместо него. Например, если управляемое приложение размещает CPython, которое, в свою очередь, использует собственные модули расширения, и вы хотите выполнить отладку всех трех проектов кода, установите флажки Python, Native и Managed . Этот подход предоставляет целостный опыт отладки, включая объединенные стеки вызовов и пошаговое выполнение во всех трех средах выполнения.
Работа с виртуальными средами
При использовании этого метода отладки в смешанном режиме для виртуальных сред (venvs), Python для Windows использует python.exe заглушку для venvs, которую Visual Studio находит и загружает в качестве подпроцесса.
Для Python 3.8 и более поздних версий смешанный режим не поддерживает многопроцессную отладку. При запуске сеанса отладки отлаживается подпроцесс заглушки, а не само приложение. В сценариях присоединения обходное решение заключается в присоединении к правильному
python.exeфайлу. При запуске приложения с отладкой (например, с помощью сочетания клавиш F5 ) можно создать venv с помощью командыC:\Python310-64\python.exe -m venv venv --symlinks. В команде вставьте предпочитаемую версию Python. По умолчанию в Windows только администраторы могут создавать символические ссылки.Для версий Python до версии 3.8 отладка смешанного режима должна работать должным образом с venvs.
Выполнение в глобальной среде не приводит к возникновению этих проблем для любой версии Python.
Установка символов Python
При первом запуске отладки в смешанном режиме может появиться диалоговое окно "Обязательные символы Python ". Необходимо установить символы только один раз для любой конкретной среды Python. Символы автоматически включаются при установке поддержки Python с помощью Установщика Visual Studio (Visual Studio 2017 и более поздних версий). Дополнительные сведения см. в разделе "Установка символов отладки для интерпретаторов Python" в Visual Studio.
Доступ к исходному коду Python
Исходный код для стандартного Python можно сделать доступным при отладке.
Перейти к
https://www.python.org/downloads/source/.Скачайте архив исходного кода Python, соответствующий вашей версии, и извлеките код в папку.
Когда Visual Studio запрашивает расположение исходного кода Python, наведите указатель на определенные файлы в папке извлечения.
Включение отладки в смешанном режиме в проекте C/C++
Visual Studio 2017 версии 15.5 и более поздних версий поддерживает отладку в смешанном режиме из проекта C/C++. Примером этого использования является внедрение Python в другое приложение, как описано в python.org.
Ниже описано, как включить отладку в смешанном режиме для проекта C/C++:
В обозревателе решений щелкните правой кнопкой мыши проект C/C++ и выберите "Свойства".
На панели "Страницы свойств" перейдите на вкладку "Свойства>конфигурации отладки ".
Разверните выпадающее меню для опции Debugger to launch и выберите Python/Native Debugging.
Замечание
Если вы не видите параметр отладки Python/Native, сначала необходимо установить собственные средства разработки Python с помощью Установщика Visual Studio. Параметр собственной отладки доступен в рабочей нагрузке разработки Python. Дополнительные сведения см. в статье "Установка поддержки Python в Visual Studio".
Нажмите кнопку "ОК" , чтобы сохранить изменения.
Отладка средства запуска программы
При использовании этого метода невозможно выполнить отладку py.exe средства запуска программы, так как она создает дочерний python.exe подпроцесс. Отладчик не подключается к подпроцессу. В этом сценарии обходное решение заключается в том, чтобы запустить python.exe программу непосредственно с аргументами, как показано ниже.
На панели "Страницы свойств " проекта C/C++ перейдите на вкладку " Свойства>конфигурации отладки ".
Для параметра Command укажите полный путь к файлу
python.exeпрограммы.Укажите нужные аргументы в поле "Аргументы команд ".
Присоединение отладчика смешанного режима
Для Visual Studio 2017 версии 15.4 и более ранних версий прямая отладка в смешанном режиме включена только при запуске проекта Python в Visual Studio. Поддержка ограничена, так как проекты C/C++ используют только собственный отладчик.
В этом сценарии обходной путь заключается в подключении отладчика отдельно:
Запустите проект C++ без отладки, выбрав "Начать без отладки" из меню
Отладка или используйте сочетание клавиш Ctrl F5 .Чтобы подключить отладчик смешанного режима к существующему процессу, выберите "Подключить отладку>к процессу". Откроется диалоговое окно.
В диалоговом окне "Присоединение к процессу" выберите соответствующий процесс из списка.
Чтобы подключиться к полю, используйте параметр "Выбрать ", чтобы открыть диалоговое окно "Выбор типа кода ".
В диалоговом окне "Выбор типа кода " выберите параметр "Отладка этих типов кода ".
В списке установите флажок Python и нажмите кнопку "ОК".
Нажмите кнопку "Присоединить" , чтобы запустить отладчик.
Подсказка
Вы можете добавить паузу или задержку в приложении C++, чтобы убедиться, что он не вызывает код Python, который необходимо выполнить отладку перед присоединением отладчика.
Изучение конкретных функций в смешанном режиме
Visual Studio предоставляет несколько функций отладки в смешанном режиме, чтобы упростить отладку приложения:
- Объединенный стек вызовов
- Шаг между Python и машинным кодом
- Представление значений PyObject в машинном коде
- Представление собственных значений в коде Python
Использование объединенного стека вызовов
В окне "Стек вызовов" отображаются нативные кадры и кадры стека Python, с переходами, помеченными между двумя типами кадров.
- Чтобы переходы отображались как [внешний код], не указывая направление перехода, используйте область"Параметры>". Разверните раздел "Общие параметры отладки>>" и установите флажок "Включить только мой код".
- Чтобы переходы отображались как [внешний код], не указывая направление перехода, используйте диалоговое окно"Параметры>". Разверните раздел"Общие> отладке", установите флажок "Включить только мой код" и нажмите кнопку "ОК".
- Чтобы сделать любой кадр вызова активным, дважды щелкните кадр. Это действие также открывает соответствующий исходный код, если это возможно. Если исходный код недоступен, кадр по-прежнему активен и локальные переменные можно проверить.
Шаг между Python и машинным кодом
Visual Studio предоставляет команды Step Into (F11) или Step Out (Shift+F11), чтобы отладчик смешанного режима правильно обрабатывал изменения между типами кода.
Когда Python вызывает метод типа, реализованного в C, шаг в вызове этого метода останавливается в начале собственной функции, реализующей метод.
Такое же поведение возникает, когда машинный код вызывает функцию API Python, которая приводит к вызову кода Python. Переход к вызову
PyObject_CallObjectна значение функции, изначально определенное в Python, останавливается на начале функции Python.Переход из Python к нативному коду также поддерживается для нативных функций, вызываемых из Python с помощью ctypes.
Использование представления значений PyObject в родном коде
Если собственный кадр (C или C++) активен, локальные переменные отображаются в окне "Локальные" отладчика. В нативных модулях расширения Python многие из этих переменных имеют тип PyObject (который является typedef для _object) или несколько других основных типов Python. В отладке в смешанном режиме эти значения представляют еще один дочерний узел с меткой [представление Python].
Чтобы просмотреть представление Python переменной, разверните узел. Представление переменных идентично тому, что вы видите, если локальная переменная, ссылающаяся на тот же объект, присутствует в кадре Python. Дочерние элементы этого узла можно редактировать.
Чтобы отключить эту функцию, щелкните правой кнопкой мыши в любом месте в окне "Локальные" и переключите меню меню"Показать узлы представления Python>":
Типы C, показывающие узлы представления Python
В следующих типах C отображаются узлы [представление Python] , если они включены:
PyObjectPyVarObjectPyTypeObjectPyByteArrayObjectPyBytesObjectPyTupleObjectPyListObjectPyDictObjectPySetObjectPyIntObjectPyLongObjectPyFloatObjectPyStringObjectPyUnicodeObject
[Представление Python] не отображается автоматически для типов, которые вы создаете самостоятельно. При создании расширений для Python 3.x это отсутствие обычно не является проблемой. Любой объект в конечном счете ob_base имеет поле одного из перечисленных типов C, что приводит к отображению [представления Python] .
Просмотр собственных значений в коде Python
Вы можете включить представление [C++] для нативных значений в окне «Локальные», когда активен фрейм Python. Эта функция по умолчанию не включена.
Чтобы включить эту функцию, щелкните правой кнопкой мыши в окне "Локальные" и выберите пункт меню "Показать узлы представления C++ в Python">.
Узел [C++ view] предоставляет представление базовой структуры C/C++ для переменной, идентичное тому, что отображается в нативном фрейме. В нем показан экземпляр
_longobject(для которогоPyLongObjectявляется типдифец) для длинного целого числа Python, и он пытается определить типы для собственных классов, которые вы создаете самостоятельно. Дочерние элементы этого узла можно редактировать.
Если дочернее поле объекта имеет тип PyObjectили другой поддерживаемый тип, он имеет узел представления [представление Python] (если эти представления включены). Это поведение позволяет перемещаться по графам объектов, где связи не имеют прямого представления в Python.
В отличие от узлов [представления Python] , использующих метаданные объекта Python для определения типа объекта, нет аналогичного надежного механизма для представления [C++]. Как правило, учитывая значение Python (т. е. ссылку), невозможно надежно определить, PyObject какая структура C/C++ поддерживает ее. Отладчик смешанного режима пытается угадать тип, просматривая различные поля типа объекта (например PyTypeObject , на него ссылается ob_type поле), которые имеют типы указателей функций. Если одна из этих указателей функции ссылается на функцию, которую можно разрешить, и эта функция имеет self параметр с типом более конкретным, чем PyObject*, то этот тип считается резервным типом.
Рассмотрим следующий пример, где ob_type->tp_init значение для заданного объекта указывает на следующую функцию:
static int FobObject_init(FobObject* self, PyObject* args, PyObject* kwds) {
return 0;
}
В этом случае отладчик может правильно вывести, что C тип объекта — FobObject. Если отладчик не может определить более точный тип из tp_init, он переходит к другим полям. Если не удается вывести тип из любого из этих полей, узел представления [C++] представляет объект как PyObject экземпляр.
Чтобы всегда получить полезное представление для пользовательских созданных типов, рекомендуется зарегистрировать по крайней мере одну специальную функцию при регистрации типа и использовать строго типизированный self параметр. Большинство типов выполняют это требование естественным образом. Для других типов проверка tp_init обычно является наиболее удобным способом для этой цели. Фиктивная реализация tp_init для типа, который присутствует исключительно для включения вывода типа отладчика, может просто возвращать ноль немедленно, как в предыдущем примере.
Просмотр различий в сравнении со стандартной отладкой Python
Отладчик смешанного режима отличается от стандартного отладчика Python. В нем представлены некоторые дополнительные функции, но не хватает некоторых возможностей, связанных с Python, как показано ниже.
- Неподдерживаемые функции включают условные точки останова, интерактивное окно отладки и кроссплатформенную удаленную отладку.
- Окно Немедленного выполнения доступно, но с частично ограниченной функциональностью, включая все ограничения, перечисленные в этом разделе.
- Поддерживаемые версии Python включают только CPython 2.7 и 3.3+.
- Чтобы использовать Python совместно с Visual Studio Shell (например, если вы установите его с использованием интегрированного установщика), в Visual Studio будет невозможно открыть проекты C++. В результате редактирование файлов C++ осуществляется на уровне базового текстового редактора. Однако отладка C/C++ и отладка в смешанном режиме полностью поддерживаются в Оболочке с исходным кодом, вхождением в нативный код и вычислением выражений C++ в окнах отладчика.
- При просмотре объектов Python в окнах инструментов "Локальные" и "Просмотр" отладчики отладчик смешанного режима отображает только структуру объектов. Он не вычисляет свойства автоматически или не отображает вычисляемых атрибутов. Для коллекций отображаются только элементы для встроенных типов коллекций (
tuple, ,list,dictset). Пользовательские типы коллекций не визуализированы как коллекции, если они не наследуются от какого-то встроенного типа коллекции. - Оценка выражений производится, как описано в следующем разделе.
Используйте вычисление выражений
Стандартный отладчик Python позволяет оценивать произвольные выражения Python в окнах "Контрольные и немедленные " при приостановке отлаживаемого процесса в любой точке кода, если он не блокируется в операции ввода-вывода или другом аналогичном системном вызове. При отладке в смешанном режиме произвольные выражения можно вычислять только в случае остановки на коде Python, после точки останова или при пошаговой обработке кода. Выражения могут вычисляться только в том потоке, в котором произошла точка останова или выполнялась операция пошагового выполнения.
Когда отладчик останавливается в машинном коде или в коде Python, где указанные условия не действуют (например, после операции завершения функции или на другом потоке). Оценка выражений ограничена доступом к локальным и глобальным переменным в области текущего выбранного кадра, доступом к их полям и индексированием встроенных типов коллекций с помощью литералов. Например, следующее выражение можно оценить в любом контексте (если все идентификаторы ссылаются на существующие переменные и поля соответствующих типов):
foo.bar[0].baz['key']
Отладчик смешанного режима также по-разному обрабатывает такие выражения. Все операции доступа к членам ищут только поля, которые непосредственно являются частью объекта (например, элемент в __dict__ или __slots__, или поле в собственной структуре, предоставляемой Python через tp_members), и игнорируют любую логику __getattr__ или __getattribute__. Аналогичным образом все операции индексирования игнорируют __getitem__и обращаются к внутренним структурам данных коллекций напрямую.
Для обеспечения согласованности эта схема разрешения имен используется для всех выражений, соответствующих ограничениям оценки ограниченных выражений. Эта схема применяется независимо от того, разрешены ли произвольные выражения в текущей точке остановки. Чтобы принудительно применить правильную семантику Python при наличии полнофункционального средства оценки, заключите выражение в скобки.
(foo.bar[0].baz['key'])