Объединить python(gui) и C++
У меня есть программа которая работает с файлами, все готово кроме интерфейса, я бы его спокойно могла бы доделать на C++, но сроки поджимают. Можно ли сделать на Python интерфейс, а на C++ функции? Ну как-нибудь из Python вызывать их?
Отслеживать
10.4k 21 21 золотой знак 25 25 серебряных знаков 53 53 бронзовых знака
задан 2 ноя 2020 в 9:19
25 3 3 бронзовых знака
2 ноя 2020 в 9:21
ctypes, cython.
2 ноя 2020 в 10:40
1 ответ 1
Сортировка: Сброс на вариант по умолчанию
Предположим, у вас есть простой пример класса C ++, который вы хотите вызвать из питона, в файле с именем foo.cpp:
#include class Foo < public: void bar()< std::cout >;
Поскольку ctypes могут взаимодействовать только с функциями C, вам необходимо предоставить те, которые объявляют их как extern «C» :
extern "C" < Foo* Foo_new()< return new Foo(); >void Foo_bar(Foo* foo)< foo->bar(); > >
Теперь компилируем это в библиотеку:
g++ -c -fPIC foo.cpp -o foo.o g++ -shared -Wl,-soname,libfoo.so -o libfoo.so foo.o
И, наконец, вам нужно написать свою оболочку(например, в fooWrapper.py):
from ctypes import cdll lib = cdll.LoadLibrary('./libfoo.so') class Foo(object): def __init__(self): self.obj = lib.Foo_new() def bar(self): lib.Foo_bar(self.obj)
Теперь все работает 😉
f = Foo() f.bar() # and you will see "Hello" on the screen
Создание расширения C++ для Python
Область применения:
Visual Studio Visual Studio для Mac
Visual Studio Code ![]()
Модули, написанные на C++ (или C), обычно используются для расширения возможностей интерпретатора Python. Они также обеспечивают доступ к низкоуровневым возможностям операционной системы.
Модули можно разделить на три следующих основных типа.
- Модули ускорения. Так как Python является интерпретируемым языком, вы можете писать модули ускорителя на C++ для повышения производительности.
- Модули-оболочки. Эти модули открывают существующие интерфейсы C/C++ для кода Python или предоставляют адаптированный API, который удобно использовать в Python.
- Модули низкоуровневого системного доступа. Эти модули создаются для доступа к низкоуровневым функциям среды выполнения CPython , операционной системы или базового оборудования.
В этой статье рассматривается создание модуля расширения C++ для CPython , который вычисляет гиперболический тангенс и вызывает его из кода Python. Подпрограмма реализована сначала на языке Python, чтобы продемонстрировать относительный прирост производительности по сравнению с реализацией той же подпрограммы на C++.
В этой статье также показаны два способа сделать расширение C++ доступным в Python:
- использование стандартных расширений CPython , как описано в документации по Python;
- использование PyBind11 (рекомендуется для C++ 11 благодаря его простоте). Для обеспечения совместимости используйте какую-то из более актуальных версий Python.
Полный пример из этого руководства см. на GitHub по ссылке python-samples-vs-cpp-extension.
Необходимые компоненты

- Visual Studio 2017 или более поздней версии с установленной рабочей нагрузкой разработки на Python. Эта рабочая нагрузка включает встроенные средства разработки Python, которые подключают рабочую нагрузку C++ и наборы инструментов, необходимые для собственных расширений.
Примечание. При установке рабочей нагрузки Приложения для обработки и анализа данных и аналитические приложения среда Python и встроенные средства разработки Python устанавливаются по умолчанию.
Дополнительные сведения о параметрах установки см. в разделе Установка поддержки Python в Visual Studio. Если вы устанавливаете Python отдельно, обязательно выберите параметр Скачать отладочные символы в разделе Дополнительные параметры установщика. Этот параметр необходим, чтобы вы могли использовать отладку в смешанном режиме между кодом Python и машинным кодом.
Создание приложения Python
- Создайте проект Python в Visual Studio, выбрав Файл>Создать>Проект.
- Выполните поиск по ключевому слову Python, выберите шаблон Приложение Python, задайте имя и расположение, а затем нажмите кнопку OK.
- В файл проекта с расширением .py вставьте следующий код. Чтобы испытать некоторые функции редактирования Python, попробуйте ввести этот код вручную. Этот код вычислит гиперболический тангенс без использования математической библиотеки, что позволит вам ускорить работу встроенных расширений.
Совет Сначала напишите код только на Python, а затем перепишите его на C++. Таким образом вам будет проще проверить правильность машинного кода.
from random import random from time import perf_counter COUNT = 500000 # Change this value depending on the speed of your computer DATA = [(random() - 0.5) * 3 for _ in range(COUNT)] e = 2.7182818284590452353602874713527 def sinh(x): return (1 - (e ** (-2 * x))) / (2 * (e ** -x)) def cosh(x): return (1 + (e ** (-2 * x))) / (2 * (e ** -x)) def tanh(x): tanh_x = sinh(x) / cosh(x) return tanh_x def test(fn, name): start = perf_counter() result = fn(DATA) duration = perf_counter() - start print('<> took seconds\n\n'.format(name, duration)) for d in result: assert -1 '.format(COUNT)) test(lambda d: [tanh(x) for x in d], '[tanh(x) for x in d] (Python implementation)')
Совет При запуске тестов производительности всегда выбирайте в меню Отладка>Запуск без отладки. Это помогает избежать дополнительных временных затрат, возникающих при запуске кода в отладчике Visual Studio.
Создание основных проектов C++
Следуйте инструкциям в этом разделе, чтобы создать два идентичных проекта C++ с именами superfastcode и superfastcode2. Позднее вы будете использовать в этих проектах разные способы предоставления кода C++ в Python.
- В обозревателе решений щелкните решение правой кнопкой мыши и последовательно выберите пункты Добавить>Новый проект. Решение Visual Studio может одновременно содержать проекты Python и C++ — это одно из преимуществ использования Visual Studio для Python.
- Выполните поиск C++, выберите Пустой проект, укажите либо superfastcode для первого проекта, либо superfastcode2 для второго проекта, а затем нажмите кнопку OK.
Совет Или, если вы установили собственные средства разработки Python в Visual Studio, можете начать с шаблона «Модуль расширения Python». В этом шаблоне уже имеется большая часть описанных здесь возможностей. Но в этом пошаговом руководстве начало работы с пустого проекта позволяет шаг за шагом продемонстрировать создание модуля расширения. Ознакомившись с процессом, в дальнейшем вы сможете использовать этот шаблон для экономии времени при написании собственных расширений.
Важно! Файл с расширением .cpp нужен, чтобы активировать страницы свойств C++ в последующих шагах.
- Для 64-разрядной среды выполнения Python активируйте конфигурацию x64.
- Для 32-разрядной среды выполнения Python следует активировать конфигурацию Win32.
Примечание. При создании собственных проектов вам понадобится настроить конфигурации и отладки, и выпуска. В этом уроке вы настроите только конфигурацию отладки и установите в ней использование сборки выпуска CPython. Эта конфигурация отключает некоторые функции отладки среды выполнения C++, в том числе утверждения. Для использования двоичных файлов отладки CPython (python_d.exe) требуются другие параметры.
| Tab | Свойство | Значение |
|---|---|---|
| Общие сведения | Имя цели | Укажите имя модуля, которое будет использоваться для ссылки на этот модуль из Python в инструкциях from. import . Это же имя будет использоваться в C++ при определении модуля для Python. Чтобы применить имя проекта в качестве имени модуля, сохраните значение по умолчанию $ . Для python_d.exe добавьте _d в конец файла. |
| Дополнительно>Расширение целевого файла | .pyd | |
| Проект по умолчанию>Тип конфигурации | Динамическая библиотека (.dll) | |
| C/C++>Общие | Дополнительные каталоги включаемых файлов | Добавьте подходящую для вашей установки папку include Python (например, c:\Python36\include ). |
| C/C++>Препроцессор | Определения препроцессора | При наличии этого свойства измените значение _DEBUG на NDEBUG для соответствия неотладочной версии CPython. Если вы используете python_d.exe, оставьте это значение без изменений. |
| C/C++>Создание кода | Библиотека времени выполнения | Выберите Многопоточная DLL (/MD) для соответствия не отладочной версии CPython. Если вы используете python_d.exe, оставьте значение Многопоточная DLL для отладки (/MDd). |
| Базовые проверки среды выполнения | По умолчанию | |
| Компоновщик>Общие | Дополнительные каталоги библиотек | Добавьте подходящую для вашей установки папку Python libs с файлами .lib (например c:\Python36\libs). Убедитесь, что указали папку libs, содержащую файлы .lib, но не папку Lib, содержащую файлы .py. |
Примечание. Если вы не видите вкладку C/C++ в свойствах проекта, значит, в проекте нет файлов, определенных как исходные файлы C/C++. Такая ситуация может возникнуть, если вы создали исходный файл без расширения .c или .cpp. Например, если в диалоговом окне создания элемента вы случайно введете module.coo вместо module.cpp, Visual Studio создаст файл, но не задаст для него тип Код C/C, что требуется для активации вкладки свойств C/C++. Такая неправильная идентификация сохранится, даже если вы переименуете файл и добавите расширение .cpp. Чтобы установить правильный тип файла, в Обозревателе решений щелкните файл правой кнопкой мыши и выберите пункт Свойства. Затем в качестве типа файлавыберите Код C/C++.
#include #include const double e = 2.7182818284590452353602874713527; double sinh_impl(double x) < return (1 - pow(e, (-2 * x))) / (2 * pow(e, -x)); >double cosh_impl(double x) < return (1 + pow(e, (-2 * x))) / (2 * pow(e, -x)); >double tanh_impl(double x) < return sinh_impl(x) / cosh_impl(x); >
Преобразование проекта C++ в расширения для Python
Чтобы преобразовать DLL-библиотеку C++ в расширение для Python, сначала нужно изменить экспортируемые методы для взаимодействия с типами Python. После этого добавьте функцию, экспортирующую модуль, а также определения методов модуля.
В последующих разделах объясняется, как выполнить эти действия с помощью расширений CPython и PyBind11.
Использование расширений CPython
Дополнительные сведения о коде, приведенном в этом разделе, см. в справочном руководстве по API Python/C, в частности на странице Объекты модуля. Не забудьте выбрать версию Python в раскрывающемся списке в правом верхнем углу.
-
В верхней части файла module.cpp включите Python.h.
#include
PyObject* tanh_impl(PyObject* /* unused module reference */, PyObject* o) < double x = PyFloat_AsDouble(o); double tanh_x = sinh_impl(x) / cosh_impl(x); return PyFloat_FromDouble(tanh_x); >
static PyMethodDef superfastcode_methods[] = < // The first property is the name exposed to Python, fast_tanh // The second is the C++ function with the implementation // METH_O means it takes a single PyObject argument < "fast_tanh", (PyCFunction)tanh_impl, METH_O, nullptr >, // Terminate the array with an object containing nulls. < nullptr, nullptr, 0, nullptr >>;
static PyModuleDef superfastcode_module = < PyModuleDef_HEAD_INIT, "superfastcode", // Module name to use with Python import statements "Provides some functions, but faster", // Module description 0, superfastcode_methods // Structure that defines the methods of the module >;
PyMODINIT_FUNC PyInit_superfastcode()
Использование PyBind11
Если вы выполнили действия из предыдущего раздела, вы наверняка заметили, что использовали много стандартного кода для создания необходимых структур модулей для кода C++. PyBind11 упрощает этот процесс с помощью макросов в файле заголовка C++, которые позволяют получить тот же результат с гораздо меньшим объемом кода.
Дополнительные сведения о коде в этом разделе см. в разделе Основы PyBind11.
- Установите PyBind11 с помощью pip: pip install pybind11 или py -m pip install pybind11 . Вы также можете установить PyBind11 с помощью окна «Окружения Python», а затем использовать его команду Открыть в PowerShell для выполнения следующего шага.
- В том же терминале выполните python -m pybind11 —includes или py -m pybind11 —includes . Это действие выводит список путей, которые следует добавить в свойство C/C++>Общие>Дополнительные каталоги включаемых файлов вашего проекта. Обязательно удалите префикс -I , если он присутствует.
- В верхнюю часть нового файла module.cpp, который не содержит изменения из предыдущего раздела, включите pybind11.h.
#include
namespace py = pybind11; PYBIND11_MODULE(superfastcode2, m)
Устранение ошибок компиляции
Модуль C++ может не компилироваться по следующим причинам.
- Ошибка: не удается обнаружить Python.h (E1696: не удается открыть исходный файл Python.h и/или C1083: не удается открыть включаемый файл: Python.h — не существует такого файла или каталога) Решение: проверьте, что путь в разделе C/C++>Общие>Дополнительные каталоги включаемых файлов в свойствах проекта указывает на папку include установки Python. См. шаг 6 в разделе Создание основного проекта C++. Дополнительные сведения о доступе к сведениям о конфигурации установки Python см . в документации по Python.
- Ошибка: не удается обнаружить библиотеки Python Решение: проверьте, что путь в разделе Компоновщик>Общие>Дополнительные каталоги библиотек в свойствах проекта указывает на папку libs установки Python. См. шаг 6 в разделе Создание основного проекта C++. Дополнительные сведения о доступе к сведениям о конфигурации установки Python см . в документации по Python.
- Ошибки компоновщика, связанные с решением целевой архитектуры: измените архитектуру проекта целевого объекта C++ на соответствие архитектуре установки Python. Например, если вы хотите использовать в проекте C++ версию Win32, но у вас установлена версия Python x64, измените проект C++ для работы с версией х64.
Тестирование кода и сравнение результатов
Теперь, когда библиотека DLL структурирована как расширения Python, можно ссылаться на них из проекта Python, импортировать модули и использовать их методы.
Предоставление доступа к библиотеке DLL для Python
Библиотеку DLL можно сделать доступной для Python несколькими способами. Покажем два метода, которые рекомендуется рассмотреть.

- Первый метод работает, если проект Python и проект C++ находятся в одном решении. Выполните следующие действия.
- В Обозревателе решений щелкните правой кнопкой мыши узел Ссылки в вашем проекте Python, а затем выберите команду Добавить ссылку.
- В открывшемся диалоговом окне перейдите на вкладку Проекты, выберите проекты superfastcode и superfastcode2 и нажмите кнопку OK.
- В другом методе устанавливается модуль в вашей среде Python, что делает этот модуль доступным и для других проектов Python. Дополнительные сведения см. в документации по проекту setuptools. Выполните следующие действия.
- Создайте в проекте C++ файл с именем setup.py, щелкнув проект правой кнопкой мыши и выбрав пункт Добавить>Новый элемент.
- Выберите Файл C++ (. cpp), назначьте этому файлу имя setup.py и нажмите кнопку OK. Если файлу назначить имя с расширением .py, это позволяет Visual Studio распознать его как файл Python, несмотря на использование шаблона файла C++. Когда файл откроется в редакторе, вставьте в него следующий код в зависимости от метода расширения. Для расширений CPython (проект superfastcode)
from setuptools import setup, Extension sfc_module = Extension('superfastcode', sources = ['module.cpp']) setup( name='superfastcode', version='1.0', description='Python Package with superfastcode C++ extension', ext_modules=[sfc_module] )
Для PyBind11 (проект superfastcode2)
from setuptools import setup, Extension import pybind11 cpp_args = ['-std=c++11', '-stdlib=libc++', '-mmacosx-version-min=10.7'] sfc_module = Extension( 'superfastcode2', sources=['module.cpp'], include_dirs=[pybind11.get_include()], language='c++', extra_compile_args=cpp_args, ) setup( name='superfastcode2', version='1.0', description='Python package with superfastcode2 C++ extension (PyBind11)', ext_modules=[sfc_module], )
[build-system] requires = ["setuptools", "wheel", "pybind11"] build-backend = "setuptools.build_meta"
Совет Если пакет уже установлен, он появится в списке. Прежде чем продолжить, щелкните значок X, чтобы удалить его.
Совет Если установка завершается неудачно из-за ошибки, связанной с разрешениями, добавьте в конец —user и попробуйте выполнить команду еще раз.
Вызов библиотеки DLL из Python
После того как вы сделаете библиотеки DLL доступными для Python, как описано в предыдущем разделе, можно вызывать функции superfastcode.fast_tanh и superfastcode2.fast_tanh2 из кода Python и сравнивать их эффективность с реализацией Python. Чтобы вызвать библиотеку DLL, выполните следующие действия.
-
Добавьте следующие строки в файл .py, чтобы вызвать методы, экспортированные из библиотек DLL, и отобразить их выходные данные.
from superfastcode import fast_tanh test(lambda d: [fast_tanh(x) for x in d], '[fast_tanh(x) for x in d] (CPython C++ extension)') from superfastcode2 import fast_tanh2 test(lambda d: [fast_tanh2(x) for x in d], '[fast_tanh2(x) for x in d] (PyBind11 C++ extension)')
Примечание. Если команда Запуск без отладки отключена, в Обозревателе решений щелкните правой кнопкой мыши проект Python и выберите команду Назначить запускаемым проектом.
Убедитесь, что подпрограммы C++ выполняются примерно в 5–20 раз быстрее, чем реализация на Python. Обычно выводится следующий результат.
Running benchmarks with COUNT = 500000 [tanh(x) for x in d] (Python implementation) took 0.758 seconds [fast_tanh(x) for x in d] (CPython C++ extension) took 0.076 seconds [fast_tanh2(x) for x in d] (PyBind11 C++ extension) took 0.204 seconds
В выходных данных вы можете увидеть, что расширение PyBind11 не такое быстрое, как расширение CPython, хотя оно все равно должно работать быстрее, чем прямая реализация на Python. Это различие в основном связано с тем, что мы использовали вызов METH_O , который не поддерживает несколько параметров, имен параметров или аргументов ключевых слов. PyBind11 формирует несколько более сложный код, чтобы предоставить вызывающим субъектам интерфейс, более похожий на Python. Но так как тестовый код вызывает функцию 500 000 раз, в результате эти дополнительные временные затраты могут сильно возрасти!
Чтобы сократить временные затраты, можно переместить цикл for в машинный код. Этот подход предполагает использование протокола итератора (или типа py::iterable из PyBind11 в качестве параметра функции) для обработки каждого элемента. Удаление повторяющихся переходов между Python и C++ является эффективным способом сокращения времени, затрачиваемого на обработку последовательности.
Устранение ошибок импорта
Если при попытке импорта модуля вы получаете сообщение ImportError , для разрешения этой проблемы можно использовать один из следующих способов.
- При сборке с помощью ссылки на проект убедитесь, что свойства проекта C++ соответствуют среде Python, активированной для проекта Python, особенно каталоги Include и Library.
- Убедитесь, что ваш выходной файл имеет имя superfastcode.pyd. Файл с любым другим именем или расширением не будет импортирован.
- Если вы установили модуль с помощью файла setup.py, убедитесь, что вы выполнили команду pip в среде Python, активированной для вашего проекта Python. При развертывании среды Python в обозревателе решений должна отображаться запись для superfastcode.
Отладка кода C++
Visual Studio поддерживает совместную отладку кода на Python и C++. В этом разделе вы пошагово выполните процесс с использованием проекта superfastcode. Этот процесс такой же, как для проекта superfastcode2.
-
В Обозревателе решений щелкните проект Python правой кнопкой мыши, выберите Свойства, откройте вкладку Отладка и выберите Отладка>Разрешить отладку машинного кода.
Совет При включении отладки машинного кода окно вывода Python может немедленно закрываться сразу после завершения программы без обычной паузы с сообщением Для продолжения нажмите любую клавишу. Решение: чтобы после включения отладки машинного кода принудительно приостановить выполнение программы, добавьте параметр -i в поле Запуск>Аргументы интерпретатора на вкладке Отладка. Этот аргумент переводит интерпретатор Python в интерактивный режим после выполнения кода, и для закрытия окна интерпретатора необходимо будет нажать клавиши CTRL+Z, а затем ВВОД. Кроме того, если вы не против изменения кода Python, можно добавить в конец программы операторы import os и os.system(«pause») . Этот код дублирует исходный запрос с приостановкой.


Альтернативные подходы
Существуют различные способы для создания расширений Python, приведенные в таблице ниже. Способы CPython и PyBind11 , указанные в первых двух строках, рассматриваются в этой статье.
| Подход | Vintage | Представители |
|---|---|---|
| Модули расширений C/C++ для CPython | 1991 | Стандартная библиотека |
| PyBind11 (рекомендуется для C++) | 2015 | |
| Cython (рекомендуется для C) | 2007 | gevent, kivy |
| HPy | 2019 | |
| mypyc | 2017 | |
| ctypes | 2003 | oscrypto |
| cffi | 2013 | cryptography, pypy |
| SWIG | 1996 | crfsuite |
| Boost.Python | 2002 | |
| cppyy | 2017 |
Связанный контент
Полный пример из этого руководства см. на GitHub по ссылке python-samples-vs-cpp-extension.
Проекты Python в Visual Studio
Область применения:
Visual Studio Visual Studio для Mac
Visual Studio Code ![]()
Приложения Python обычно определяются только с помощью файлов и папок, но такая структура может усложнить работу, так как приложения увеличиваются в размере и могут содержать автоматически сгенерированные файлы, JavaScript для веб-приложений и т. д. Проект Visual Studio помогает управлять этими сложными моментами. Проект (файл .pyproj) определяет все исходные файлы и файлы содержимого, связанные с проектом, содержит сведения о сборке каждого файла, хранит информацию для интеграции с системами управления версиями и помогает упорядочить приложение в виде логических компонентов.

Кроме того, проекты всегда управляются в решении Visual Studio, которое может содержать любое число проектов с возможностью ссылаться друг на друга. Например, проект Python может ссылаться на проект C++, который реализует модуль расширения. Благодаря этой связи Visual Studio автоматически создает проект C++ (при необходимости), когда вы запускаете отладку проекта Python. (Общие сведения см. в статье Решения и проекты в Visual Studio.)
Visual Studio предоставляет множество шаблонов проектов Python, позволяющих быстро настроить несколько структур приложений, а также шаблон для создания проекта из существующего дерева папок и шаблон для создания пустого проекта. Список шаблонов см. в разделе Шаблоны проектов.
В Visual Studio 2019 можно открыть папку с кодом Python и выполнить этот код, не создавая проект Visual Studio и файлы решения. Дополнительные сведения см . в кратком руководстве. Открытие и запуск кода Python в папке. Но файл проекта имеет ряд важных преимуществ, которые мы описали в этой статье.
Все версии Visual Studio нормально работают с кодом Python даже без проекта. Например, можно открыть сам файл Python и выполнить автозавершение и отладку, а также использовать функцию IntellSense. Для этого щелкните правой кнопкой мыши в редакторе и выберите пункт Запуск с отладкой. Такой код всегда использует глобальное окружение по умолчанию, однако при работе могут возникать неверные завершения или ошибки, если код предназначен для другого окружения. Кроме того, Visual Studio анализирует все файлы и пакеты в папке, из которой открыт один файл, что может значительно расходовать время ЦП.
Проект Visual Studio можно создать из существующего кода, как описано в разделе Создание проекта из существующих файлов.
Добавление файлов, назначение файла запуска и настройка сред
При разработке приложения обычно требуется добавить в проект новые файлы различных типов. Чтобы это сделать, щелкните правой кнопкой мыши проект, выберите Добавить>Существующий элемент и перейдите к нужному файлу. Можно также выбрать Добавить>Новый элемент. Появится диалоговое окно с различными шаблонами элементов. Как описано в справочнике по шаблонам элементов, доступны такие варианты: пустые файлы Python, класс Python, модульный тест и различные файлы, связанные с веб-приложениями. Вы можете испробовать эти варианты с помощью тестового проекта, чтобы узнать о возможностях вашей версии Visual Studio.
Каждый проект Python имеет один назначенный файл запуска, выделенный полужирным шрифтом в обозревателе решений. Это файл, который запускается, когда вы запускаете отладку (F5 или Отладка>Начать отладку) или выполняете проект в интерактивном окне (SHIFT+ALTF+5 или Отладка>Выполнить проект в интерактивном окне Python). Чтобы изменить его, щелкните правой кнопкой мыши новый файл и выберите действие Назначить автозапускаемым элементом (или Задать как файл запуска в ранних версиях Visual Studio).
Если удалить выбранный файл запуска из проекта и не выбрать новый, Visual Studio не будет знать, с какого файла Python нужно начинать выполнение проекта. В этом случае в Visual Studio 2017 версии 15.6 и более поздних версий возникает ошибка. В более ранних версиях либо открывается окно вывода с запущенным интерпретатором Python, либо окно вывода появляется, но почти сразу же исчезает. Если у вас возникла подобная ситуация, убедитесь, что назначен файл запуска.
Чтобы окно вывода оставалось открытым, щелкните правой кнопкой мыши проект, выберите Свойства, откройте вкладку Отладка, а затем добавьте -i в поле Аргументы интерпретатора. Этот аргумент вынуждает интерпретатор перейти в интерактивный режим после завершения программы, оставив окно открытым, пока вы не нажмете клавиши CTRL+Z>ВВОД для выхода.
Новый проект всегда по умолчанию связан с глобальной средой Python. Чтобы связать проект с другим окружением (в том числе виртуальным), в проекте щелкните правой кнопкой мыши узел Окружения Python и выберите команду Добавить окружение. , а затем выберите нужные окружения. Можно также использовать элемент управления с раскрывающимся списком окружений на панели инструментов, чтобы выбрать окружение или добавить в проект новое.

Чтобы изменить активное окружение, в обозревателе решений щелкните правой кнопкой мыши нужное окружение и выберите действие Активировать окружение. Дополнительные сведения см. в разделе о выборе окружения для проекта.

Шаблоны проектов
Visual Studio предоставляет несколько способов настройки проекта Python — с нуля или из существующего кода. Чтобы использовать шаблон, выберите команду меню Файл>Создать>Проект или щелкните правой кнопкой мыши решение в обозревателе решений и выберите Добавить>Новый проект. В любом случае отобразится диалоговое окно Новый проект. Чтобы просмотреть шаблоны, относящиеся к Python, выполните поиск по «Python» или выберите узел Python языка>:

В следующей таблице перечислены шаблоны, доступные в Visual Studio 2022:
| Template | Description |
|---|---|
| На основе существующего кода Python | Создает проект Visual Studio из существующего кода Python в структуре папок. |
| Приложение Python | Структура базового проекта для нового приложения Python с одним пустым исходным файлом. По умолчанию проект выполняется в консоли интерпретатора глобальной среды по умолчанию, которую можно изменить, назначив другую среду. |
| Веб-проекты | Проекты для веб-приложений на базе различных платформ, включая Bottle, Django и Flask. |
| Фоновое приложение (Интернет вещей) | Поддерживает развертывание проектов Python для работы в качестве фоновых служб на устройствах. Дополнительные сведения см. на странице центра разработчиков Интернета вещей Windows. |
| Модуль расширения Python | Этот шаблон отображается в области Visual C++, если вы уже установили Собственные средства разработки Python с рабочей нагрузкой Python в Visual Studio 2017 или более поздней версии (см. раздел Установка). Он предоставляет базовую структуру для библиотеки DLL расширения C++, как описано в статье Создание расширения C++ для Python. |
В следующей таблице перечислены шаблоны, доступные в Visual Studio 2019 (не все шаблоны доступны в предыдущих версиях).
| Template | Description |
|---|---|
| На основе существующего кода Python | Создает проект Visual Studio из существующего кода Python в структуре папок. |
| Приложение Python | Структура базового проекта для нового приложения Python с одним пустым исходным файлом. По умолчанию проект выполняется в консоли интерпретатора глобальной среды по умолчанию, которую можно изменить, назначив другую среду. |
| Веб-проекты | Проекты для веб-приложений на базе различных платформ, включая Bottle, Django и Flask. |
| Приложение с IronPython | Аналогичен шаблону приложения Python, но по умолчанию использует интерпретатор IronPython, поддерживающий взаимодействие .NET и смешанный режим отладки с использованием языков .NET. |
| Приложение WPF с IronPython | Структура проекта, использующая IronPython с XAML-файлами Windows Presentation Foundation для пользовательского интерфейса приложения. Visual Studio предоставляет конструктор пользовательского интерфейса XAML, возможность написания кода программной части на Python, а также возможность запуска приложения без отображения консоли. |
| Веб-страница с IronPython и Silverlight | Это проект IronPython, который выполняется в браузере с подключаемым модулем Silverlight. Код приложения Python добавляется на веб-страницу в виде скрипта. Стандартный тег скрипта получает часть кода JavaScript, который инициализирует IronPython, выполняющийся в Silverlight, откуда код Python может взаимодействовать с моделью DOM. |
| Приложение Windows Forms с IronPython | Структура проекта, использующая IronPython с пользовательским интерфейсом, созданным с помощью кода и Windows Forms. Приложение запускается без вывода консоли. |
| Фоновое приложение (Интернет вещей) | Поддерживает развертывание проектов Python для работы в качестве фоновых служб на устройствах. Дополнительные сведения см. на странице центра разработчиков Интернета вещей Windows. |
| Модуль расширения Python | Этот шаблон отображается в области Visual C++, если вы уже установили Собственные средства разработки Python с рабочей нагрузкой Python в Visual Studio 2017 или более поздней версии (см. раздел Установка). Он предоставляет базовую структуру для библиотеки DLL расширения C++, как описано в статье Создание расширения C++ для Python. |
Так как Python является интерпретируемым языком, проекты Python в Visual Studio не создают отдельный исполняемый файл, как это делают проекты, написанные на других компилируемых языках программирования (например, C#). Дополнительные сведения см. в разделе вопросов и ответов.
Создание проекта на основе имеющихся файлов
Описанный здесь процесс не перемещает и не копирует исходные файлы. Если вы хотите работать с копией, сначала создайте дубликат папки.

- Запустите Visual Studio и выберите Файл>Создать>Проект.
- В диалоговом окне Создание проекта выполните поиск по запросу «Python», выберите шаблон На основе существующего кода Python, укажите имя и расположение проекта, а затем нажмите кнопку ОК.
- В появившемся мастере задайте путь к существующему коду, фильтр для типов файлов и любые пути поиска, необходимые для проекта, а затем нажмите кнопку Далее. Если вы не знаете пути поиска, оставьте это поле пустым.
- В следующем диалоговом окне выберите файл запуска для проекта и нажмите кнопку Далее. При необходимости выберите среду; в противном случае оставьте значения по умолчанию.
Примечание. В диалоговом окне отображаются только файлы в корневой папке. Если нужный файл находится во вложенной папке, не указывайте файл запуска и укажите его позже в Обозревателе решений (см. инструкции ниже).

Связанные файлы
![]()
Связанные файлы — это файлы, которые добавлены в проект, но при этом находятся за пределами папок проекта приложения. Они отображаются в Обозреватель решений как обычные файлы со значком ярлыка:
Связанные файлы указаны в файле PYPROJ с помощью элемента . Связанные файлы могут быть неявными, если они используют относительный путь за пределами структуры каталогов, или явными, если они используют пути в обозревателе решений:
MyProject\test2.py
Связанные файлы игнорируются при выполнении любого из следующих условий:
- Связанный файл содержит метаданные связи, и путь, указанный в атрибуте Include, находится в пределах каталога проекта.
- Связанный файл дублирует файл, который существует в иерархии проекта.
- Связанный файл содержит метаданные связи, и путь является относительным путем вне иерархии проекта.
- Путь связи является корневым.
Работа со связанными файлами
Чтобы добавить существующий элемент в качестве связи, щелкните правой кнопкой мыши папку проекта, в которую вы хотите добавить файл, а затем выберите Добавить>Существующий элемент. В открывшемся диалоговом окне выберите файл и щелкните Добавить как связь в раскрывающемся списке кнопки Добавить. Если конфликтующие файлы отсутствуют, эта команда создает связь в выбранной папке. Связь не добавится, если файл с таким именем уже существует или связь с этим файлом уже существует в проекте.
При попытке создать связь с файлом, который уже существует в папке проекта, он добавляется как обычный файл, а не как связанный. Чтобы преобразовать файл в связь, выберите Файл>Сохранить как и сохраните файл в расположение вне иерархии проекта. Visual Studio автоматически преобразует его в связь. Аналогичным образом можно преобразовать связь обратно с помощью команды Файл>Сохранить как и сохранить файл в иерархии проекта.
При перемещении связанного файла в обозревателе решений связь также перемещается, но фактический файл при этом не затрагивается. Аналогичным образом, удаление связи приведет к удалению только связи, не затрагивая сам файл.
Связанные файлы нельзя переименовать.
Ссылки
Проекты Visual Studio поддерживают добавление ссылок на проекты и расширения, которые отображаются в узле Ссылки в обозревателе решений.

Ссылки на расширения обычно указывают зависимости между проектами и используются для обеспечения IntelliSense во время разработки или связывания во время компиляции. Проекты Python используют ссылки подобным образом, но из-за динамической природы Python они в основном используются во время разработки для предоставления усовершенствованной функции IntelliSense. Они также могут использоваться для развертывания в Microsoft Azure с целью установки дополнительных зависимостей.
Модули расширений
Ссылка на файл PYD позволяет использовать IntelliSense для созданного модуля. Visual Studio загружает файл PYD в интерпретатор Python и анализирует его типы и функции. Программа также пытается выполнить синтаксический анализ строк функций в документе, чтобы предоставить справку по сигнатурам.
Если в любой момент модуль расширения обновляется на диске, Visual Studio повторно анализирует модуль в фоновом режиме. Это не влияет на поведение во время выполнения, но некоторые варианты завершения остаются недоступными до завершения анализа.
Необходимо добавить путь поиска к папке, содержащей модуль.
Проекты .NET
При работе с IronPython можно добавить ссылки на сборки .NET, чтобы активировать использование IntelliSense. Для проектов .NET в решении щелкните правой кнопкой мыши узел Ссылки в проекте Python, выберите Добавить ссылку, щелкните вкладку Проекты и найдите нужный проект. Для библиотек DLL, которые вы скачали отдельно, выберите вкладку Обзор и перейдите к требуемой библиотеке DLL.
Так как ссылки в IronPython недоступны до вызова clr.AddReference(») , в сборку также нужно добавить соответствующий вызов clr.AddReference . Обычно он добавляется в начале кода. Например, код, созданный шаблоном проекта IronPython Windows Forms (доступно в Visual Studio 2019) в Visual Studio, включает два вызова в верхней части файла:
import clr clr.AddReference('System.Drawing') clr.AddReference('System.Windows.Forms') from System.Drawing import * from System.Windows.Forms import * # Other code omitted
Проекты WebPI
Можно добавить ссылки на записи продукта WebPI для развертывания в облачных службах Microsoft Azure, где можно установить дополнительные компоненты с помощью веб-канала WebPI. По умолчанию отображаемый веб-канал предназначен только для Python и содержит Django, CPython и другие основные компоненты. Также можно выбрать собственный веб-канал, как показано ниже. При публикации в Microsoft Azure задача установки устанавливает все продукты, на которые имеются ссылки.
Проекты WebPI недоступны в Visual Studio 2017 или Visual Studio 2019.
Пишем десктоп-приложение на Python с помощью Tkinter
Знакомимся с библиотекой Tkinter — пишем на Python кросс-платформенный калькулятор, который рассчитывает вес человека.


Иллюстрация: Merry Mary для Skillbox Media

Антон Яценко
Изучает Python, его библиотеки и занимается анализом данных. Любит путешествовать в горах.
Десктопные приложения пишут на разных языках программирования: C++, C#, C, Python и других. Начинающим разработчикам проще всего использовать Python и его библиотеки для работы над графическими интерфейсами.
Одна из таких библиотек — Tkinter. Она входит в стандартный пакет Python и позволяет создавать приложения для Windows, mac OS и Linux. Давайте разберёмся, как устроена эта библиотека, и напишем десктопный калькулятор, помогающий рассчитать вес человека.
Что такое GUI и как с ним работать в Python
GUI (Graphical User Interface) — это графический интерфейс пользователя, оболочка программы, с которой мы взаимодействуем с помощью клавиатуры и мыши. На современных операционных системах почти все программы работают с графическим интерфейсом, и мы каждый день сталкиваемся с GUI: читаем статьи в браузере, набираем текст в редакторе или играем в игры.
Противоположность графическому интерфейсу — командная строка, позволяющая управлять приложением с помощью текстовых команд. Такой интерфейс реализован в терминале macOS и командной строке Windows.
Для работы с GUI в Python есть четыре библиотеки:
Мы выбрали Tkinter, потому что она не требует дополнительной установки и позволяет быстро создавать приложения с простым графическим интерфейсом.
Знакомимся с Tkinter
Tkinter — это удобный интерфейс для работы со средствами Tk. Приложения, созданные на основе этой библиотеки, кросс-платформенные, то есть могут запускаться на разных операционных системах.
Схематично работу с Tkinter можно представить в виде четырёх шагов:

Что здесь происходит:
- Мы подключаем библиотеку Tkinter с помощью директивы import.
- Создаём главное окно приложения, в котором будут размещаться все графические элементы.
- Добавляем виджеты — визуальные элементы, выполняющие определённые действия.
- Создаём главный цикл событий — он включает в себя все события, происходящие при взаимодействии пользователя с интерфейсом.
Ключевые объекты в работе с Tkinter — виджеты. Это аналоги тегов из HTML, которые позволяют создавать интерактивные и неинтерактивные элементы, например надписи или кнопки. Всего их 18, но чаще всего используют следующие:
- Button — кнопки;
- Canvas — «холст», на котором рисуют графические фигуры;
- Entry — виджет для создания полей ввода;
- Label — контейнер для размещения текста или изображения;
- Menu — виджет для создания пунктов меню.
Понять работу с виджетами легче всего на практике. Но прежде чем к ней приступить, обсудим идею нашего первого десктопного приложения.
Создаём калькулятор для расчёта индекса массы тела
Мы напишем калькулятор индекса массы тела. ИМТ — это важный медицинский показатель, который позволяет оценить, есть ли у человека избыточный вес или ожирение. Он рассчитывается по следующей формуле:
ИМТ = вес (в кг) / рост 2 (в метрах)
Результаты расчётов оценивают с помощью специальной таблицы. У врачей она имеет много градаций, мы же воспользуемся упрощённой версией:

Шаг 1
Запускаем Python и импортируем Tkinter
Писать код на Python лучше всего в специальной IDE, например в PyCharm или Visual Studio Code. Они подсвечивают синтаксис и предлагают продолжение кода — это сильно упрощает работу программиста. Весь код из этой статьи мы писали в Visual Studio Code.
Библиотека Tkinter предустановлена в Python. Поэтому её нужно только импортировать:
Шаг 2
Делаем эскиз интерфейса и продумываем логику приложения
Прежде чем писать код, необходимо ответить на несколько вопросов:
- Какие данные мы хотим получить от пользователя и в каком виде?
- Какое событие будет запускать расчёт ИМТ: нажатие кнопки, получение приложением всех необходимых данных или что-то другое?
- Как будем показывать результат?
В нашем случае необходимо получить от пользователя вес и рост в виде целых чисел. При этом вес должен быть введён в килограммах, а рост — в сантиметрах. ИМТ будет рассчитываться по нажатии кнопки, а результат — выводиться во всплывающем окне в виде значения ИМТ и категории, к которой он относится.
Схематично графический интерфейс нашего калькулятора будет выглядеть так:

Теперь попробуем реализовать интерфейс и работу калькулятора с помощью Python и Tkinter.
Шаг 3
Создаём основное окно и указываем название приложения
После импорта библиотеки в Python загрузим её методы:

Мы не указали размер окна, поэтому название приложения не помещается в него полностью. Исправим это с помощью метода geometry:

Шаг 4
Создаём виджет Frame для контроля за расположением элементов
В окне приложения необходимо разместить несколько элементов с нашего эскиза: два поля ввода информации с подписями и одну кнопку. Важно, чтобы поля не накладывались друг на друга и не уходили за пределы окна. В Tkinter для этого есть несколько методов:
- pack — используется, когда мы работаем с контейнерами для элементов. Позволяет позиционировать кнопки, надписи или другие элементы внутри контейнеров.
- place — позволяет позиционировать элементы, указывая точные координаты.
- grid — размещает элементы по ячейкам условной сетки, разделяющей окно приложения.
Мы воспользуемся комбинацией методов pack и grid. Для начала создадим виджет Frame для размещения надписей, полей ввода и кнопок. Подробное описание работы виджета есть в документации. Мы же используем только два свойства: padx и pady.
Обозначим отступы по вертикали и горизонтали в 10 пикселей для элементов, которые будут расположены внутри Frame:

Сейчас элемент расположен в центре окна, но он займёт правильное положение, когда мы напишем другие элементы.
Добавим вторую надпись о весе аналогичным образом, но при позиционировании в grid укажем следующую, четвёртую строку:

Теперь добавим поля для ввода пользовательской информации, используя виджет Entry:

Всё получилось. Остаётся по аналогии добавить поле ввода веса:

Теперь добавим кнопку, которая будет запускать расчёт ИМТ. Сделаем это с помощью виджета Button:

Теперь в приложении есть все графические элементы. Остаётся лишь написать код, который будет получать информацию из виджетов Entry и рассчитывать индекс массы тела.
Шаг 6
Получаем информацию из виджетов Entry и рассчитываем индекс массы тела
Напишем простую функцию и разберём её построчно:
Всё работает. Функция получает данные из полей ввода и рассчитывает индекс массы тела, показывая результат на экране.
Приведём код полностью без комментариев
from tkinter import * from tkinter import messagebox def calculate_bmi(): kg = int(weight_tf.get()) m = int(height_tf.get())/100 bmi = kg/(m*m) bmi = round(bmi, 1) if bmi < 18.5: messagebox.showinfo('bmi-pythonguides', f'ИМТ = соответствует недостаточному весу') elif (bmi > 18.5) and (bmi < 24.9): messagebox.showinfo('bmi-pythonguides', f'ИМТ = соответствует нормальному весу') elif (bmi > 24.9) and (bmi < 29.9): messagebox.showinfo('bmi-pythonguides', f'ИМТ = соответствует избыточному весу') else: messagebox.showinfo('bmi-pythonguides', f'ИМТ = соответствует ожирению') window = Tk() window.title('Калькулятор индекса массы тела (ИМТ)') window.geometry('400x300') frame = Frame( window, padx=10, pady=10 ) frame.pack(expand=True) height_lb = Label( frame, text="Введите свой рост (в см) " ) height_lb.grid(row=3, column=1) weight_lb = Label( frame, text="Введите свой вес (в кг) ", ) weight_lb.grid(row=4, column=1) height_tf = Entry( frame, ) height_tf.grid(row=3, column=2, pady=5) weight_tf = Entry( frame, ) weight_tf.grid(row=4, column=2, pady=5) cal_btn = Button( frame, text='Рассчитать ИМТ', command=calculate_bmi ) cal_btn.grid(row=5, column=2) window.mainloop()
Что дальше?
Узнать о возможностях Tkinter и особенностях работы с виджетами можно в официальной документации. А если хотите найти больше реальных примеров для практики, советуем две книги:
- Python GUI Programming with Tkinter. Develop responsive and powerful GUI applications with Tkinter, Алан Мур.
- Tkinter GUI Programming by Example, Дэвид Лав.
Больше интересного про код в нашем телеграм-канале. Подписывайтесь!