152

Is there something similar to os.path.dirname(path), but in pathlib?

dreftymac
  • 31,404
  • 26
  • 119
  • 182
trainset
  • 2,079
  • 3
  • 13
  • 17

3 Answers3

238

It looks like there is a parents element that contains all the parent directories of a given path. E.g., if you start with:

>>> import pathlib
>>> p = pathlib.Path('/path/to/my/file')

Then p.parents[0] is the directory containing file:

>>> p.parents[0]
PosixPath('/path/to/my')

...and p.parents[1] will be the next directory up:

>>> p.parents[1]
PosixPath('/path/to')

Etc.

p.parent is another way to ask for p.parents[0]. You can convert a Path into a string and get pretty much what you would expect:

>>> str(p.parent)
'/path/to/my'

And also on any Path you can use the .absolute() method to get an absolute path:

>>> os.chdir('/etc')
>>> p = pathlib.Path('../relative/path')
>>> str(p.parent)
'../relative'
>>> str(p.parent.absolute())
'/etc/../relative'

Note that os.path.dirname and pathlib treat paths with a trailing slash differently. The pathlib parent of some/path/ is some:

>>> p = pathlib.Path('some/path/')
>>> p.parent
PosixPath('some')

While os.path.dirname on some/path/ returns some/path:

>>> os.path.dirname('some/path/')
'some/path'
larsks
  • 277,717
  • 41
  • 399
  • 399
  • 1
    I don't know what a "shared folder" is. My advice would be to try it and see if it works. If it doesn't work and you require further assistance, your best option is probably to post a new question (because comments aren't a great place for extended questions and answers). – larsks May 10 '18 at 12:37
  • For some reason, `p.parent[0]` and `p.parent[1]` doesn't work on Macs because indexing is not supported. Use `p.parent` for current directory and use `p.parent.parent` to go up one directory. – Oliver Oliver Jun 24 '19 at 06:29
  • 5
    @OliverOliver `p.parents[0]`, with the `s`. – smitelli Jul 13 '19 at 02:28
  • 4
    I would add the option `p.parent.resolve()` to get the resolved absolute path. – Berci Jul 18 '19 at 13:15
  • 23
    Use ```p.parent.name``` to get the parent directory's name without the entire path – BrettJ Sep 24 '20 at 00:56
  • Why doesn't `parents[-1]` work? Any other way to get the last parent? – Alaa M. Apr 20 '22 at 07:15
  • `parents[-1]` works just fine, but will always (under Linux, at least) return `/`, because that's always the last parent. – larsks Apr 20 '22 at 13:05
  • @larsks - It doesn't work at all for me. It raises an `IndexError` – Alaa M. May 06 '22 at 14:01
  • @AlaaM. if you are seeing unexpected behavior, you may want to open a new question, and provide the code that reproduces the problem. – larsks May 06 '22 at 14:02
  • @larsks nah it's just not supported – Alaa M. May 09 '22 at 06:44
10

summary

from pathlib import Path
file_path = Path("/Users/yuanz/PycharmProjects/workenv/little_code/code09/sample.csv")

1. get dir path

file_path.parent
# >>> /Users/yuanz/PycharmProjects/workenv/little_code/code09

2. get filename

file_path.name
# >>> sample.csv

3. get file type

file_path.suffix

# >>> .csv

4.add new file in this dir path

file_path.parent.joinpath("dd.png")
yuanzz
  • 1,359
  • 12
  • 15
-7

I came here looking for something very similar. My solution, based on the above by @larsks, and assuming you want to preserve the entire path except the filename, is to do:

>>> import pathlib
>>> p = pathlib.Path('/path/to/my/file')
>>> pathlib.Path('/'.join(list(p.parts)[1:-1])+'/')

Essentially, list(p.parts)[1:-1] creates a list of Path elements, starting from the second to n-1th, and you join them with a '/' and make a path of the resulting string. Edit The final +'/' adds in the trailing slash - adjust as required.

betontalpfa
  • 3,454
  • 1
  • 33
  • 65
Mo S
  • 11
  • 3
  • 1
    My only issue with this solution is that it's assuming '/' is the path splitter. Which it IS if you're in unix, but it's not if you're in Windows...I was looking for a more 'elegant' solution since my issue which is the same requires OS independence... – InfOracle Jan 26 '21 at 14:29
  • 1
    That's why I wrapped everything in Path() - if I understand correctly, doing so makes the output compliant with whichever OS. But I forgot to add `pathlib.` to the last line.. – Mo S Jan 26 '21 at 17:43
  • Besides losing the leading `/`, which is probably not what you want, what is the advantage to just doing `p.parent`? – johnson Jan 28 '21 at 08:17
  • None - I misunderstood `p.parent` :\ – Mo S Jan 28 '21 at 23:29