Любопытное поведение в sys.path при изменении томов в Windows CMD - PullRequest
4 голосов
/ 14 марта 2019

Я только что заметил странное поведение sys.path и Windows CMD и хотел бы знать, что происходит и почему.

В следующих двух примерах я распечатываю sys.path, меняю громкость на D:, cd в каталог, снова меняю громкость на C: и, наконец, снова печатаю 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. Обратите внимание, что PYTHONPATH без изменений.

Я не мог воспроизвести такое же поведение с PowerShell; оба PYTHONPATH s показывают первое поведение.

Как я уже сказал, мне было бы очень интересно узнать, что здесь происходит.

1 Ответ

2 голосов
/ 14 марта 2019

CMD устанавливает условно скрытую переменную среды с именем "= D:" для рабочего каталога на диске D :. Процесс Python наследует эту переменную среды, и Windows API использует ее при вызове GetFullPathNameW, чтобы разрешить относительный путь к диску "D:" как полный путь.

В CMD мы можем перечислить все переменные окружения, включая «скрытые», через set «». Эта команда зависит от ошибки, но она существовала так долго, что теперь стала функцией. Чтобы перечислить только скрытые, используйте 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...