Импорт установленного модуля среды выполнения с использованием pip в python 3

Я хочу установить и импортировать модули Python 3 во время выполнения.

Я использую следующую функцию для установки модулей во время выполнения с помощью pip:

def installModules(modules):
    for module in modules:
        print("Installing module {}...".format(module))

        subprocess.call([sys.executable, "-m", "pip", "install", "--user", module])

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

modules = [ "wget", "zipfile2" ]
installModules(module)
import wget

Я получаю ModuleNotFoundError. Если после этого я начну еще один сеанс Python 3, я смогу использовать модули, например. wget, что означает, что модули были установлены, но недоступны для текущего сеанса Python 3.

Возможно ли в Python 3 установить, а затем импортировать установленные модули в том же сеансе Python 3, то есть сразу после установки?

Спасибо!

Обновлено:

На новой установке Ubuntu 19.04 внутри VirtualBox после sudo apt-get install python3-pip запустите следующий скрипт:

import os, sys
import subprocess


def installModules(modules):
    for module in modules:
        print("Installing module {}...".format(module))

        subprocess.call([sys.executable, "-m", "pip", "install", "--user", module])

def process():
    modulesToInstall = [ "wget", "zipfile2" ]
    installModules(modulesToInstall)

process()

import wget

def main():
    wget.download("http://192.168.2.234/test/configure.py")

if __name__ == "__main__":
    main()

Я получил:

user@user-VirtualBox:~$ python3 script.py
Installing module wget...
Collecting wget
Installing collected packages: wget
Successfully installed wget-3.2
Installing module zipfile2...
Collecting zipfile2
  Using cached https://files.pythonhosted.org/packages/60/ad/d6bc08f235b66c11bbb76df41b973ce93544a907cc0e23c726ea374eee79/zipfile2-0.0.12-py2.py3-none-any.whl
Installing collected packages: zipfile2
Successfully installed zipfile2-0.0.12
Traceback (most recent call last):
  File "script.py", line 17, in <module>
    import wget
ModuleNotFoundError: No module named 'wget'

Версия Python 3:

user@user-VirtualBox:~$ python3 --version
Python 3.7.3

Версия pip3:

user@user-VirtualBox:~$ pip3 --version
pip 18.1 from /usr/lib/python3/dist-packages/pip (python 3.7)

Другая информация:

user@user-VirtualBox:~$ whereis python3
python3: /usr/bin/python3.7m /usr/bin/python3.7-config /usr/bin/python3.7 /usr/bin/python3 /usr/bin/python3.7m-config /usr/lib/python3.7 /usr/lib/python3.8 /usr/lib/python3 /etc/python3.7 /etc/python3 /usr/local/lib/python3.7 /usr/include/python3.7m /usr/include/python3.7 /usr/share/python3 /usr/share/man/man1/python3.1.gz

Есть идеи?

@JohnHennig Спасибо за ваше время, посмотрите мои правки

Jacob Krieg 11.07.2019 13:56
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
3
1
639
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

По умолчанию при запуске Питон добавляет пользовательские сайт-пакетыдиректор (я буду называть его УСПД) в пути поиска модулей. Но это происходит только в том случае, если каталог существует в файловой системе (на диске). Я не нашел никакой официальной документации, подтверждающей это утверждение 1, поэтому я потратил некоторое время на отладку и задавался вопросом, почему все кажется таким странным.

Вышеупомянутое поведение оказывает большое влияние на этот конкретный сценарий (pip install --user). Учитывая состояние (при запуске) процесса Питон, который будет устанавливать модули:

  1. УСПД существует:

    • Все просто, все работает Ok
  2. УСПД не существует:

    • Установка модуля создаст его
    • Но, поскольку его нет в путях поиска модулей, все установленные там модули не будут доступны для (простых) операторов импорт.

При запуске другого процесса Питон он попадет под №1.

Чтобы исправить положение, необходимо вручную добавить УСПД в пути поиска модулей. Вот как должно выглядеть (начало) скрипта:

import sys
import os
import subprocess
import site

user_site = site.getusersitepackages()
if user_site not in sys.path:
    sys.path.append(user_site)

# ...

@EDIT0:

1 Я только что наткнулся на [Python]: PEP 370 -- Каталог пакетов сайтов для каждого пользователя -- Реализация (акцент мой):

The site module gets a new method adduserpackage() which adds the appropriate directory to the search path. The directory is not added if it doesn't exist when Python is started.

Другие вопросы по теме