从另一个Python安装

时间:2015-09-11 09:02:23

标签: python powershell python-3.4 windows-server-2012 python-venv

我在Windows Server 2012上运行多个Python安装。我可能会找到解决此问题的方法,但我很好奇发生了什么。我担心会彻底改变安装,以防我破坏其他人可能不知道的Python计划任务。

(下面的所有代码框都是PowerShell)。

PS C:\> C:\Python34\Scripts\pip.exe list
jdcal (1.0)
pip (7.1.2)
setuptools (12.0.5)
virtualenv (13.1.2)

虽然这个Python 3.4安装没有安装Django,但它似乎从Python 33x86安装中获取了版本。这是正常的吗?

PS C:\> C:\Python34\python.exe -c "import django; print(django.get_version())"
1.6.5
PS C:\> C:\Python33x86\python.exe -c "import django; print(django.get_version())"
1.6.5

我已经创建了一个基于Python 3.4的Python virtualenv,并在其中安装了Django 1.8.4。做一个"点子列表"确认已正确安装: -

PS C:\> D:\PyVirtualEnvs\example_py34\Scripts\activate.bat
PS C:\> D:\PyVirtualEnvs\example_py34\Scripts\pip.exe list | Select-String "Django "
Django (1.8.4)

然而,当我在virtualenv中导入时,我得到Django版本1.6.5: -

PS C:\> D:\PyVirtualEnvs\example_py34\Scripts\python.exe -c "import django; print(django.get_version())"
1.6.5

这是virtualenv中的错误还是我错过了什么?

编辑:它可能与this question有关吗?​​

EDIT2:使用pyvenv时会发生同样的事情,如ham-sandwich所示。

3 个答案:

答案 0 :(得分:1)

对我来说唯一看起来很奇怪的是你正在运行

for(Thread t: threads) {
    try{
        t.join();
    } catch(InterruptedException e) {}
}
当有一个activate.ps1时,在powershell中

。我不知道是否存在兼容性问题。

答案 1 :(得分:1)

如果从PowerShell运行cmd.exe shell脚本(批处理文件),PowerShell会生成cmd.exe的实例来运行脚本(批处理文件)。如果批处理文件设置环境变量,则它们仅存在于生成的cmd.exe实例中。一旦该实例终止(即,当脚本结束时),环境变量不会传播到调用进程(在本例中为PowerShell)。这是设计的。

如果要传播环境变量,可以在PowerShell中使用以下Invoke-CmdScript函数:

function Invoke-CmdScript {
  param(
    [String] $scriptName
  )
  $cmdLine = """$scriptName"" $args & set"
  & $Env:SystemRoot\system32\cmd.exe /c $cmdLine |
  Select-String '^([^=]*)=(.*)$' | ForEach-Object {
    $varName = $_.Matches[0].Groups[1].Value
    $varValue = $_.Matches[0].Groups[2].Value
    Set-Item Env:$varName $varValue
  }
}

以下文章中有关此内容的更多信息:

Windows IT Pro: Take Charge of Environment Variables in PowerShell

在您的情况下,您将运行:

PS C:\> Invoke-CmdScript D:\PyVirtualEnvs\example_py34\Scripts\activate.bat

这将生成activate.bat并传播环境变量更改。

答案 2 :(得分:0)

我发现了这种行为的原因。 PYTHONPATH环境变量设置为机器上不寻常位置的Python安装。

根据the documentation,当在当前目录中找不到模块时,PYTHONPATH用作导入位置。

  

当导入名为spam的模块时,解释器首先搜索具有该名称的内置模块。如果未找到,则会在变量sys.path给出的目录列表中搜索名为spam.py的文件。 sys.path从这些位置初始化:

     
      
  • 包含输入脚本(或当前目录)的目录。
  •   
  • PYTHONPATH(目录名列表,语法与shell变量PATH相同)。
  •   
  • 依赖于安装的默认值。
  •   

由于某些原因,激活/取消激活脚本未设置/取消设置PYTHONPATH。它确实设置了PYTHONHOME,但这似乎不会影响进口。这感觉就像是virtualenv和pyvenv中的一个错误(我试过了两个)。

原始的activate.bat脚本更改了一个“set”变量,该变量不会影响$ env:PYTHONPATH。 Activate.ps1尝试将原始PYTHONPATH保存在变量中,将其设置为虚拟环境目录,然后在取消激活时,恢复原始PYTHONPATH。这些都不再起作用,可能是由于Powershell或Python更新。

我们的解决方案是修改激活和停用脚本(PoSh或bat)以在两个硬编码值之间切换PYTHONPATH。