我刚刚注意到sys.path
和Windows CMD的某些奇怪行为,并且想知道正在发生什么以及为什么。
在以下两个示例中,我打印出sys.path
,将音量更改为D:
,将cd
更改为目录,将音量更改为C:
,最后打印出{ {1}}。
我使用两个非常相似的sys.path
来做到这一点。
使用PYTHONPATH
:
PYTHONPATH=D:\
一切都如预期。
使用C:\Users\z003w3we>python -c "import sys; print(sys.path)"
['', 'D:\\', <others>]
C:\Users\z003w3we>D:
D:\>cd UserData
D:\UserData>C:
C:\Users\z003w3we>python -c "import sys; print(sys.path)"
['', 'D:\\', <others>]
(注意缺少结尾的PYTHONPATH=D:
):
\
现在,我们突然C:\Users\z003w3we>python -c "import sys; print(sys.path)"
['', 'D:\\', <others>]
C:\Users\z003w3we>D:
D:\>cd UserData
D:\UserData>C:
C:\Users\z003w3we>python -c "import sys; print(sys.path)"
['', 'D:\\UserData', <others>]
C:\Users\z003w3we>echo %PYTHONPATH%
D:
中有D:
,而不是D:\UserData
。请注意,sys.path
保持不变。
我无法使用PowerShell重现相同的行为;这两个PYTHONPATH
都表现出第一个行为。
正如我所说,我会对了解这里发生的事情非常感兴趣。
答案 0 :(得分:2)
CMD为驱动器D:上的工作目录设置了一个常规的隐藏环境变量,名为“ = D:”。 Python进程继承了此环境变量,并且在调用GetFullPathNameW
来将驱动器相对路径“ D:”解析为完全限定路径时,Windows API会使用它。
在CMD中,我们可以通过设置“”列出所有环境变量,包括“隐藏”的变量。该命令依赖于一个错误,但由于存在已久,以至于现在已成为一项功能。要仅列出隐藏的对象,请使用set "" | findstr /r "^="
。例如:
C:\>set "" | findstr /r "^="
=C:=C:\
C:\>cd /d E:\UserData
E:\UserData>c:
C:\>set "" | findstr /r "^="
=C:=C:\
=E:=E:\UserData
C:\>set PYTHONPATH=E:
C:\>python -c "import sys; print(sys.path[1]); sys.exit(0xFF)"
E:\UserData
C:\>set "" | findstr /r "^="
=C:=C:\
=E:=E:\UserData
=ExitCode=000000FF