在python 3中使用pip导入运行时安装的模块 [英] Import runtime installed module using pip in python 3
问题描述
我想在运行时安装和导入Python 3
模块.
I want to install and import Python 3
modules at runtime.
我正在使用以下功能在运行时使用pip
安装模块:
I'm using the following function to install modules at runtime using pip
:
def installModules(modules):
for module in modules:
print("Installing module {}...".format(module))
subprocess.call([sys.executable, "-m", "pip", "install", "--user", module])
该模块已成功安装,但是安装完成后,我无法在运行时导入它.所以,如果我这样做:
The module is installed successfully, but I'm not able to import it at runtime, after the installation finishes. So if I do:
modules = [ "wget", "zipfile2" ]
installModules(module)
import wget
我得到一个ModuleNotFoundError
.在那之后,如果我开始另一个Python 3会话,则可以使用模块,例如wget
,表示已经安装了模块,但不适用于当前的Python 3会话.
I get a ModuleNotFoundError
. If, after that, I start another Python 3 session, I am able to use the modules e.g. wget
, which means that the modules have been installed, but they are not available for this current Python 3 session.
在Python 3中是否可以在同一Python 3会话中即在安装后立即安装并导入已安装的模块?
Is it possible in Python 3 to install and then import the installed modules in the same Python 3 session i.e. right after installation?
谢谢!
在sudo apt-get install python3-pip
之后,在VirtualBox内的全新Ubuntu 19.04上安装,运行以下脚本:
On a fresh Ubuntu 19.04 install inside VirtualBox, after a sudo apt-get install python3-pip
, running the following script:
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版本是:
The Python 3 version is:
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
有什么想法吗?
推荐答案
默认情况下,启动时 Python 添加用户站点包 dir (在模块搜索路径中,我将其称为 USPD ).但这仅在目录存在于文件系统(磁盘)上时发生.我没有找到任何官方文档来支持此声明 1 ,因此我花了一些时间进行调试,并想知道为什么事情看起来如此怪异
By default, at startup Python adds the user site-packages dir (I'm going to refer to it as USPD) in the module search paths. But this only happens if the directory exists on the file system (disk). I didn't find any official documentation to support this statement 1, so I spent some time debugging and wondering why things seem to be so weird.
以上行为对此特定方案(pip install --user
)具有重大影响.考虑将要安装模块的 Python 进程的状态(启动时):
The above behavior has a major impact on this particular scenario (pip install --user
). Considering the state (at startup) of the Python process that will install modules:
-
USPD 存在:
- 事情很简单,一切正常确定
USPD 不存在:
- 模块安装将创建它
- 但是,由于它不在模块搜索路径中,因此那里安装的所有模块将无法用于(简单的) import 语句
启动另一个 Python 进程时,它将属于 #1.
When another Python process is started, it will fall under #1.
要解决问题,应将 USPD 手动添加到模块搜索路径. (开头)脚本如下所示:
To fix things, USPD should be manually added to module search paths. Here's how the (beginning of the) script should look like:
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 :
@EDIT0:
1 I just came across [Python]: PEP 370 -- Per user site-packages directory - Implementation (emphasis is mine):
站点模块获取一个新方法 adduserpackage(),该方法将适当的目录添加到搜索路径中. 如果在启动Python时该目录不存在,则不会添加该目录.
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.
这篇关于在python 3中使用pip导入运行时安装的模块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!