David258
David258

Reputation: 757

Pythons finding parent directory alternatives

There seems to be (at least) two different methods of getting a parent directory path in Python, both of which I've seen in common usage. Are the following equivalent or am I missing something?

os.path.dirname(my_dir)

os.path.join(my_dir, os.pardir)

The former is shorter, but possibly less clear (especially when going up more than 1 layer). I'm struggling to think of any other possible uses for os.pardir or os.path.pardir?

Zen of Python: "There should be one-- and preferably only one --obvious way to do it"

Upvotes: 2

Views: 657

Answers (3)

Aran-Fey
Aran-Fey

Reputation: 43136

They're not equivalent.

The difference lies in how paths ending with os.sep are handled:

>>> os.path.dirname('/foo/bar/')
'/foo/bar'

But:

>>> os.path.join('/foo/bar/', os.pardir)
'/foo/bar/..'
>>> os.path.abspath('/foo/bar/..')
'/foo'

So which one should you use? Neither. Use the pathlib module instead:

>>> from pathlib import Path
>>> Path('/foo/bar/').parent
PosixPath('/foo')
>>> str(Path('/foo/bar/').parent)
'/foo'

If you absolutely cannot use pathlib, stick with os.path.dirname. Scenarios where you want to have a pardir segment (..) in your file paths are extremely rare and they're more likely to cause problems than anything else.

Upvotes: 1

Batman
Batman

Reputation: 8917

Those two things aren't equivalent. If you read the documentation you'll see that dirname is just returning the directory of the path your provide.

So os.path.dirname("/foo/bar/file.txt") will return /foo/bar and os.path.dirname("/foo/bar/") will also return /foo/bar

As the name suggests, os.path.join joins path fragments together.

So if I wanted to get /foo/bar/file.txt I could use os.path.join("/foo/bar/", "file.txt"). In the example you've given, os.path.join("/foo/bar/", os.pardir) would give /foo/bar/...

The other way that does often get used is:

parent, _ = os.path.split("/foo/bar/file.txt")

Where parent is the parent directory, and the value assigned to _ is file.txt. The reason for this is that split and dirname are doing two slightly different things. split is returning the name of the parent directory, and the file name, whereas dirname is returning only the first part, and essentially a shorthand method for the line above.

There really aren't a lot of use cases for pardir. If you want to see some, check out this.

Upvotes: 0

bharathkallurs
bharathkallurs

Reputation: 109

Check the following lines. The parent directory is given by the first one (in this case, for html it is /var/www). os.pardir shows a '..' which is a constant used almost by most of the Windows and POSIX based OSes to refer a parent directory. When you do a join on it with 'my_dir', you get my_dir + '..' which is not what you might need.

>>> import os
>>> a = "/var/www/html"
>>> os.path.dirname(a)
'/var/www'
>>> os.path.join(a, os.pardir)
'/var/www/html/..'
>>> 

Upvotes: 0

Related Questions