Импорт установленного модуля во время выполнения с помощью pip в Python 3 - PullRequest
2 голосов
/ 10 июля 2019

Я хочу установить и импортировать 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

Есть идеи?

1 Ответ

3 голосов
/ 16 июля 2019

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

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

  1. USPD существует:

    • Все просто, все работает ОК
  2. USPD не существует:

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

Когда запускается другой процесс Python , он попадает под # 1.

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

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 - Каталог пользовательских пакетов сайта - Реализация ( упор мой):

Модуль сайта получает новый метод adduserpackage () , который добавляет соответствующий каталог в путь поиска. Каталог не добавляется, если он не существует при запуске Python .

...