Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Documentation describing this python windows os.chdir behavior?

Tags:

python

chdir

I learned today that in python on windows, doing os.chdir('f:\\') is very different than doing os.chdir('f:'). The command with the trailing backslash actually changes the current directory. Without the backslash, the command is like typing f: in the command prompt, and changes the current directory to the last current directory on the f drive.

Here's an example:

import time
import os
if __name__ == '__main__':
    os.chdir('f:\\directory')
    print 'cwd is {}'.format(os.getcwd())
    os.chdir('d:\\directory')
    print 'cwd is {}'.format(os.getcwd())
    os.chdir('f:')
    print 'cwd is {}'.format(os.getcwd())
    os.chdir('f:\\')
    print 'cwd is {}'.format(os.getcwd())

prints

cwd is f:\directory
cwd is d:\directory
cwd is f:\directory
cwd is f:\

I can understand why this difference is useful, but couldn't find anything documenting this behavior. I'd gotten used to leaving trailing slashes off my directories as I usually use here strings...

Is this behavior documented anywhere? Can I rely on it not changing?

like image 781
aggieNick02 Avatar asked Jul 22 '26 10:07

aggieNick02


2 Answers

This isn't a Python feature, it's a general Windows feature.

On Windows, every drive keeps track of its own current working directory. So really, "the current working directory" is the current working directory of the current drive.

  • chdir('F:') changes the drive to F, but doesn't change F's working directory, so you end up changing to the current directory of the F drive.

  • chdir('F:\\') changes the drive to F, and changes F's working directory to its root, so you end up changing to the root directory of the F drive.

It's also not specific to chdir. Any function that deals with pathnames, even open, will act this way.

*open('F:spam.txt') opens the file spam.txt in the F drive's current working directory (even if your current drive is, say, C). (This is consistent with the way DOS-style tools work.)

*open('F:\\spam.txt') opens the file spam.txt in the F drive's root directory.


Some cross-platform tools try to instead pretend the drives are top-level mount points, so cd F: is like cd /f/, and does go to the root of F. This has the advantage of making native Windows and Cygwin builds of your program work very similarly, but the disadvantage of making your program not work like traditional DOS-style programs. In general, more tools do things the way Python does—it gives you more flexibility, and is usually less confusing.


As you added in a comment:

Apart from the "Can I rely on it not changing", I mean who can tell what Microsoft will break in their newly announced 'improved' console.

Well, this behavior goes back to… I think PC-DOS 2.0, or whenever they first added directories. And if they ever were going to improve this, they'd presumably do it by getting rid of the drive-and-path for something either more flexible, or more POSIX-like. (Although UNC paths and \\.\… "raw" paths are already arguably both more flexible and more POSIX-like, and they didn't get rid of the drive-and-dir system when they added those in NT…)

like image 109
abarnert Avatar answered Jul 24 '26 00:07

abarnert


The documentation mentions this behavior for another function in the same module. Its probably safe to assume that they will be handled the same way:

Note that since there is a current directory for each drive, os.path.join("c:", "foo") represents a path relative to the current directory on drive C: (c:foo), not c:\foo.

https://docs.python.org/3/library/os.path.html

However, the comment by abarnert is correct. The behavior is caused by how Windows interprets paths.

like image 23
Anonymous Avatar answered Jul 23 '26 23:07

Anonymous



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!