os.system('F:')
spawns a child shell process (i.e. the %ComSpec%
shell, which is usually cmd.exe) and changes its working directory. It does not (and cannot) change the working directory of the parent process.
Note that the working directory is not stored per thread, i.e. it's not stored in the thread environment block (TEB) but process-wide in the process environment block (PEB). Generally avoid modifying the working directory in a multithreaded application. Instead use relative or fully-qualified paths.
Bonus Trivia: DOS Emulation
In addition to the process current working directory, Windows (the C runtime, actually) tracks the working directory on every DOS drive (e.g. C:) in hidden environment variables such as =C:
. The initial '=' character keeps these variables from being displayed by the shell's set
command, and it also filters them out of the C runtime environ
that Python uses for os.environ
. A bug in the command prompt will show these hidden variables if you pass an empty string to the set
command, e.g. set ""
. Or in Python use ctypes to call GetEnvironmentVariable
:
>>> from ctypes import *
>>> kernel32 = WinDLL('kernel32')
>>> kernel32.GetEnvironmentVariableW('=C:', None, 0)
8
>>> path = create_unicode_buffer(8)
>>> kernel32.GetEnvironmentVariableW('=C:', path, 8)
7
>>> path.value
'C:\\Temp'
Windows uses these hidden variables, if they exist, to resolve drive-relative paths. That said, the C runtime _chdir
function is actually what creates/modifies them. A Windows program that only calls SetCurrentDirectory
instead of POSIX chdir
won't remember the per-drive working directory. Python's home-grown implementation of chdir
on Windows has to implement this magic. See win32_chdir
(3.4.3 source, Modules/posixmodule.c, line 1398).