При выполнении os.system('python myscript.py') получаю ошибку ModuleNotFoundError

def paint():
    os.system('python paint.py')

В общем, с помощью фрагмента кода выше я из другого кода запускаю код который мне нужен, paint.py имеет импорты нескольких библиотек :


import math
import time
import cv2
import mediapipe as mp
import numpy as np

И при запуске кода paint.py, он работает, но когда я запускаю его с помощью первого фрагмента кода, вылетает ошибка


  File "F:\.....\Smart\paint.py", line 4, in <module>
    import cv2
ModuleNotFoundError: No module named 'cv2'

Хотя у меня всё установлено, в чём может быть проблема? python 3.11 ; Win 10.


Ответы (2 шт):

Автор решения: Vitalizzare

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

Если мы говорим о Unix-подобной системе, то одним из вариантов решения может быть создание скрипта, который выполняется как самостоятельная команда. Вот пример, как это обычно делается:

#!/usr/local/bin/python3.12

import re
import sys
from mypy.__main__ import console_entry
if __name__ == '__main__':
    sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
    sys.exit(console_entry())

Это скрипт запуска mypy из командной строки. В первой строке указан полный путь к той версии Python, которая должна его выполнить. В моём случае это python 3.12, тогда как версия системного пайтона 2.7. То есть, без дополнительных настроек как системы, так и пайтоновского окружения, команда python -m mypy вернет мне ошибку.

Действия с вашей стороны зависят от системы, в которой вы работаете, равно как и от статуса скрипта paint.py. Например:

  • Если это самостоятельная программа и мы говорим о Linux, тогда создайте код её запуска подобно приведенному выше и замените проблемную строку на os.system('paint') (при этом сама система должна видеть paint как команду).
  • Если это часть проекта, то почему бы не импортировать paint.py как модуль?
  • Если программа, внутри которой запускается paint.py, выполняется один раз и будет выброшена после получения результата, то достаточно указать в проблемной строке полный путь к python, который используете вы как пользователь. Примите во внимание, что программа paint.py может быть разработана в другом виртуальном окружении. Чтобы запустить её из командной строки, нужно или активировать это окружение, или указать полный путь к версии python из этого окружения.
→ Ссылка
Автор решения: Serge3leo

os.system('python paint.py')

На мой вкус, так себе вариант, поскольку в системе может быть установлено 33 Python, и у каждого свой набор модулей. И всё это зависит от переменных окружения, cmd/sh и прочего, прочего...

В принципе, в "тяжёлых" виртуальных окружениях типа conda это, обычно, не вызывает проблем, т.к. они виртуализируют очень много, вплоть до компиляторов C/C++/Fortran, не забывая и о cmd/sh и переменных окружения и путях поиска. Но в более легковесных виртуальных окружениях или вообще без них, всё сложнее.

Во многих случаях надежней (или понятнее) запустить точно тот же самый Python:

import subprocess
import sys

def paint():
    subprocess.run([sys.executable, "paint.py"])

Таким образом, запускается в точности тот же Python, у которого точно такой же набор модулей (ну, если os.environ не портить).

→ Ссылка