Python 2.7 Python重新加载pip不';行不通

Python 2.7 Python重新加载pip不';行不通,python-2.7,Python 2.7,我目前正在尝试升级pip,然后在python脚本中安装paramiko,因为脚本本身使用paramiko。下面是一个简单的例子,我正在努力完成 import pip try: import paramiko except ImportError: pip.main(["install", "--upgrade", "pip"]) reload(pip) pip.main(["install", "--user", "paramik

我目前正在尝试升级pip,然后在python脚本中安装paramiko,因为脚本本身使用paramiko。下面是一个简单的例子,我正在努力完成

import pip

try:
        import paramiko
except ImportError:
        pip.main(["install", "--upgrade", "pip"])
        reload(pip)
        pip.main(["install", "--user", "paramiko"])
        import paramiko

ssh = paramiko.SSHClient()
我正在使用Python2.7在Ubuntu16.04虚拟机上运行这个脚本,该虚拟机没有paramiko和pip版本8.1.1。对于运行脚本后的pip升级输出,我得到:

收集pip下载pip-9.0.1-py2.py3-none-any.whl(1.3MB) 100% |████████████████████████████████| 1.3MB 712kB/s安装收集的软件包:pip成功安装了您正在使用的pip-8.1.1 pip版本8.1.1,但版本9.0.1可用。你应该 考虑通过“PIP安装-升级PIP”命令升级。

之后,它尝试按预期安装paramiko,但失败了,因为它基本上无法安装paramiko使用的加密依赖项。但是,如果它使用的是升级后的pip,这将不是一个问题。我已将VM恢复到以前的快照,以便通过执行以下操作手动安装paramiko

pip install --upgrade pip
pip install --user paramiko
在shell中,它可以工作,但我需要能够在脚本中执行此操作

注意,我还将VM还原为以前的快照,并尝试在shell中使用上述命令安装paramiko,但没有首先执行pip升级,正如预期的那样,我得到的错误与尝试安装paramiko时脚本给出的错误相同。 现在我已经做了一些测试,尝试在脚本中包含以下内容:

pip.main(["install", "--upgrade", "pip"])
reload(pip)
pip.main(["install", "--upgrade", "pip"])
reload(pip)
至于输出,我得到如下结果:

收集pip
下载pip-9.0.1-py2.py3-none-any.whl(1.3MB)

您应该考虑通过“PIP安装升级PIP”命令进行升级。 收集pip
使用缓存的pip-9.0.1-py2.py3-none-any.whl

安装收集的软件包:pip已成功安装pip-8.1.1

您使用的是pip版本8.1.1,但版本9.0.1可用

您应该考虑通过“PIP安装升级PIP”命令进行升级。


注意第二次pip升级时如何使用缓存的pip-9.0.1。这是否意味着在重新加载之后,脚本将使用pip 9.0.1?如果是这样,为什么paramiko安装不使用升级的pip?如何让paramiko使用升级后的pip?

是否尝试从sys.modules阵列中删除pip包

导入pip
导入系统
导入站点
打印(“PIP版本:”+PIP.\uuuuuuuuuuuuuuu版本)
main([“安装”、“升级”、“pip”])
user\u path=site.getusersitepackages()
系统路径=site.getsitepackages()
sys.path=[user\u path]+system\u path+sys.path
pips=[如果module.startswith('pip'),则sys.modules中的模块对应模块]
对于pip中的pip_模块:
系统模块pop(pip_模块)
德尔皮普
进口pip
打印(“PIP版本:”+PIP.\uuuuuuuuuuuuuuu版本)
在安装了pip 8.1.1的机器上运行时,我得到的输出是:

 begnini@coffee-machine:~# python update.py
 PIP Version: 8.1.1
 Collecting pip
  Downloading pip-9.0.1-py2.py3-none-any.whl (1.3MB)
    100% |████████████████████████████████| 1.3MB 651kB/s
 Installing collected packages: pip
  Found existing installation: pip 8.1.1
    Uninstalling pip-8.1.1:
      Successfully uninstalled pip-8.1.1
 Successfully installed pip-9.0.1
 PIP Version: 9.0.1
编辑:正如我们所讨论的,问题在于pip试图首先在pythonlib主目录中搜索,而不是/usr/local/libdir。为了解决这个问题,我在系统路径数组的第一个位置添加了本地lib dir。通过这个修改,这个bug应该被修复了


编辑2:添加的站点路径改为使用硬编码的目录。

因此,在进行一些挖掘之后,看起来这是一个已修补的目录。不幸的是,我可能无法始终控制将运行此脚本的计算机(即无法应用修补程序),因此我的解决方案只是在Exception部分中的paramiko第二次导入失败时使用os.execl()重新启动脚本

至于bug,总之,在pip升级之后,报告了错误的版本,但是pip升级了。因此,如果再次运行脚本,将使用新版本的pip,这允许正确安装paramiko,因此解决方案是重新启动脚本

由于python文档对os.execl()的使用不是很清楚,请遵循

我的代码现在的外观示例:

import pip
import sys
import os

try:
        import paramiko
except ImportError:
        pip.main(["install", "--upgrade", "pip"])
        pip.main(["install", "--user", "paramiko"])
        try:
            import paramiko
        except ImportError:
            os.execl(sys.executable, 'python', __file__, *sys.argv[1:])

ssh = paramiko.SSHClient()

您可能需要在此之前运行
sudo apt get install build sential libssl dev libffi dev python dev-y
,因为加密库需要它们。我现在正试图避免使用sudo,因为此脚本可能稍后在权限受限的VM上运行,我也在尽量减少对系统的安装/更改量。因此,我尝试了您的解决方案,但仍然不起作用。我从字面上复制并粘贴了您拥有的内容,对于升级前的版本,我有8.1.1(预期),但升级后的版本仍然是8.1.1。有趣的是,在脚本运行之后,如果我要重新运行脚本或者只是从shell中检查版本,我会得到9.0.1。就像脚本必须在更改生效之前结束一样。此外,在升级过程中,我的输出消息与您的不同,我没有收到“发现现有…”和“卸载…”消息。在这里,我已经“成功安装了8.1.1”。脚本是否可能只是使用了一个过时的缓存版本?或者只是在错误的文件夹中查找?阅读您的回复,我认为您的pip安装了apt,对吗(python pip)?对于apt,pip目录是
/usr/lib/python2.7/dist packages/pip
,更新后,新的pip目录是
/usr/lib/python2.7/dist packages/pip
。您可以在升级pip之前确认此打印
pip.\uuuu路径\uuuuu
。请执行以下操作:['/usr/lib/python2.7/dist packages/pip']。升级pip:['/home/user1/.local/lib/python2.7/site packages/pip']后,这是否意味着脚本不能使用新的pip版本,因为它位于新目录中?是否可以将pip升级到我在脚本中指定的目录,然后以脚本将使用该目录中的pip的方式重新加载pip?
import pip
import sys
import os

try:
        import paramiko
except ImportError:
        pip.main(["install", "--upgrade", "pip"])
        pip.main(["install", "--user", "paramiko"])
        try:
            import paramiko
        except ImportError:
            os.execl(sys.executable, 'python', __file__, *sys.argv[1:])

ssh = paramiko.SSHClient()