我在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所示。
答案 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。