我一直将#!/usr/bin/env python3
用于python脚本,因为Debian发行版通常将python
用于2.7版,将python3
用于3.x版,更改此约定可能会导致问题。在系统中(例如,请参见此问题How to update-alternatives to Python 3 without breaking apt?)。
但是,我无法使其在Windows上正常工作。考虑一台具有标准python(从https://www.python.org/downloads/下载)并以管理员身份安装给所有用户的计算机。这是一个打印可执行文件和(基本)前缀的脚本:
#!/usr/bin/env python3
import os, sys, platform
print('EXECUTABLE: ' + sys.executable)
print('PREFIX: ' + sys.prefix)
print('BASE PREFIX: ' + sys.base_prefix)
现在看以下内容:
PS C:\pytest> gcm python | select Source
C:\Program Files\Python37\python.exe
PS C:\pytest> gcm python3 | select Source
C:\Users\user\AppData\Local\Microsoft\WindowsApps\python3.exe
如您所见,Windows上的python3.exe是一个“存根”,它将在页面上打开Microsoft Store以便从中安装Python。我提到这一点是为了防止重大影响。但是,运行上面的脚本会得到正确的结果:
PS C:\pytest> .\script.py
EXECUTABLE: C:\Program Files\Python37\python.exe
PREFIX: C:\Program Files\Python37
BASE PREFIX: C:\Program Files\Python37
不幸的是,如果我创建并激活虚拟环境:
PS C:\pytest> python -m venv .venv
PS C:\pytest> . .\.venv\Scripts\Activate.ps1
(.venv) PS C:\pytest> .\script.py
EXECUTABLE: C:\Program Files\Python37\python.exe
PREFIX: C:\Program Files\Python37
BASE PREFIX: C:\Program Files\Python37
我不明白为什么会这样,因为根据PEP-486,Python启动器应该能够检测到活跃的病毒环境。它似乎确实与shebang中的版本限定符有关。如果我将脚本修改为使用#!/usr/bin/env python
,它似乎可以正常工作:
(.venv) PS C:\pytest> .\script.py
EXECUTABLE: C:\pytest\.venv\Scripts\python.exe
PREFIX: C:\pytest\.venv
BASE PREFIX: C:\Program Files\Python37
如开头所述,我不想修改脚本以使用没有版本限定符的shebang。在使用python3 shebang时,有什么方法可以配置python启动器以正确检测虚拟环境? documentation on shebang lines明确声明:
上面的任何虚拟命令都可以带有显式版本(仅是主版本,或者是主版本和次版本)后缀。
此外,它指出:
shebang行的/ usr / bin / env格式还有另一个特殊属性。在查找已安装的Python解释器之前,此表单将在可执行文件PATH中搜索Python可执行文件。
但是,即使尝试为我的虚拟环境将python.exe复制为python3.exe,它似乎也不起作用:
(.venv) PS C:\pytest> copy .\.venv\Scripts\python.exe .\.venv\Scripts\python3.exe
(.venv) PS C:\pytest> gcm python3 | select Source
Source
------
C:\pytest\.venv\Scripts\python3.exe
(.venv) PS C:\pytest> .\script.py
EXECUTABLE: C:\Program Files\Python37\python.exe
PREFIX: C:\Program Files\Python37
BASE PREFIX: C:\Program Files\Python37
即使python3.exe在PATH中可见,python启动器仍会忽略虚拟环境并选择系统安装...
更新:我在another StackExchange question中找到了如何删除将您带到Microsoft Store的python3.exe存根的方法,并删除了它以查看它是否有所不同。什么都没改变,所以这个问题完全在python启动器中。
更新2:这是通过设置PYLAUNCH_DEBUG = 1启用调试信息之后的信息
(.venv) PS C:\pytest> $env:PYLAUNCH_DEBUG=1
(.venv) PS C:\pytest> .\script.py
launcher build: 32bit
launcher executable: Console
File 'C:\Users\user\AppData\Local\py.ini' non-existent
File 'C:\WINDOWS\py.ini' non-existent
Called with command line: "C:\pytest\script.py"
maybe_handle_shebang: read 168 bytes
maybe_handle_shebang: BOM not found, using UTF-8
parse_shebang: found command: python3
locating Pythons in 64bit registry
locate_pythons_for_key: unable to open PythonCore key in HKCU
locate_pythons_for_key: "C:\Program Files\Python37\python.exe" is a 64bit executable
locate_pythons_for_key: "C:\Program Files\Python3\PCbuild\win32\python.exe: The filename, directory name, or volume label syntax is incorrect.
locate_pythons_for_key: "C:\Program Files\Python3\PCbuild\amd64\python.exe: The filename, directory name, or volume label syntax is incorrect.
locate_pythons_for_key: "C:\Program Files\Python3\PCbuild\python.exe: The filename, directory name, or volume label syntax is incorrect.
locating Pythons in native registry
locate_pythons_for_key: unable to open PythonCore key in HKCU
locate_pythons_for_key: unable to open PythonCore key in HKLM
found no configured value for 'python3'
search for Python version '3' found '"C:\Program Files\Python37\python.exe"'
run_child: about to run '"C:\Program Files\Python37\python.exe" "C:\pytest\script.py" '
EXECUTABLE: C:\Program Files\Python37\python.exe
PREFIX: C:\Program Files\Python37
BASE PREFIX: C:\Program Files\Python37
child process exit code: 0
更新3:在Mark建议这只是一个错误之后,我提出了an issue in the python bug tracker并等待确认。