4

I have looked on Stack Overflow everywhere but I cant find a solution to this problem.

Given that I have a folder/file as string: "/path1/path2/path3/file" how can I get the parent folder and its parent folder. In other words if I want to traverse up one level "/path1/path2/path3" or two levels "/path1/path2" how can I get those string values from the original string path in python?

Please note that I don't simply want the pieces of the path (in other words not a list of ['path1', 'path2', 'path3']) but instead "/path1/path2/path3".

asked Oct 6, 2016 at 11:23
4
  • 2
    Possible duplicate of How to split a dos path into its components in Python Commented Oct 6, 2016 at 11:26
  • os.path.realpath(__file__) will give you string that contains path to your file, and then just apply string manipulation to shorten it. Commented Oct 6, 2016 at 11:28
  • 2
    os.path.dirname? and apply it n times to go up n levels... Commented Oct 6, 2016 at 11:51
  • No, "this is not what [he] asked for". Lol... Commented Oct 6, 2016 at 11:58

6 Answers 6

6

os.path.dirname() (doc) is the way to go. It returns the directory which contains the object pointed by the path:

>>> import os.path
>>> os.path.dirname('/path1/path2/path3/file')
'/path1/path2/path3'

In this case, you want the "grandparent" directory, so just use the function twice:

>>> parent = os.path.dirname('/path1/path2/path3/file')
>>> os.path.dirname(parent)
'/path1/path2'

If you want to do it an arbitrary number of times, a function can be helpful here:

def go_up(path, n):
 for i in range(n):
 path = os.path.dirname(path)
 return path

Here are some examples:

>>> go_up('/path1/path2/path3/file', 1)
'/path1/path2/path3'
>>> go_up('/path1/path2/path3/file', 2)
'/path1/path2'
>>> go_up('/path1/path2/path3/file', 3)
'/path1'
answered Oct 6, 2016 at 11:30
Sign up to request clarification or add additional context in comments.

Comments

5

You can use the pathlib module:

>>> path = pathlib.PurePath('/file1/file2/file3/file')
>>> path.parts
('/', 'file1', 'file2', 'file3', 'file')
>>> os.path.join(*path.parts[:-2])
'/file1/file2'

So just put path.parts[:-n] for n levels up.

Alternatively you can use the parents attribute:

>>> path = pathlib.PurePath('/file1/file2/file3/file4/file5/file6')
>>> path.parents[0]
PurePosixPath('/file1/file2/file3/file4/file5')
>>> path.parents[1]
PurePosixPath('/file1/file2/file3/file4')
>>> path.parents[4]
PurePosixPath('/file1')

So to go up n levels just use parents[n-1].

To convert a *Path object to a string just call str on it:

>>> str(path)
'/file1/file2/file3/file4/file5/file6'
answered Oct 6, 2016 at 12:03

Comments

4

additionally to all other answers, you can also use os.path.join function with the os.path.pardir variable which usually equals ...

>>> path = "some/random/path/to/process"
>>> parent = os.path.pardir
>>> grand_parent_path = os.path.join(path, parent, parent)
>>> grand_parent_path
'some/random/path/to/process\\..\\..'

If you don't want to repeat parent several times, you can use a multipled list:

>>> os.path.join(path, *([parent] * 3))
'some/random/path/to/process\\..\\..\\..'

The result is quite ugly, so you can use the os.path.normpath function to make it prettier:

>>> os.path.normpath(os.path.join(path, *([parent] * 3)))
'some\\random'

Important note: Doing so, you are sure your code is portable

answered Oct 6, 2016 at 11:43

Comments

1

os.path.split will do it for you. There are many other interesting functions in there.

answered Oct 6, 2016 at 11:25

2 Comments

Split the pathname path into a pair, (head, tail) where tail is the last pathname component and head is everything leading up to that. How can I traverve two or 3 levels up?
@RFVenter Call the function multiple times on the result?
0

os.path.dirname gives you the parent directory.

answered Oct 6, 2016 at 11:26

6 Comments

This is not what I asked for.
Yes it is what you asked for. >>> os.path.dirname("/path1/path2/path3/file") '/path1/path2/path3'
Citing the question: 'or two levels'
2 levels: os.path.dirname(os.path.dirname("/path1/path2/path3/file")) ...
Write a function that takes a path and a level and applies level times os.path.dirname on the path?
|
0
'/'.join (originalPath.split ('/') [:-2])

It will take you 2 levels up.

brandizzi
27.4k9 gold badges111 silver badges172 bronze badges
answered Oct 6, 2016 at 11:25

4 Comments

This may fail, for example, if the path is a Windows path using `` as separator.
Yes, but the question was about a Linux path. By the way, as a habit I always convert paths to Linux paths. But admitted, os.path is the generally accepted toolbox for the job. I like a small toolbox, though, sometimes I can't find the hammer anymore...
It can be resolved by replacing '/' by os.path.sep
@JacquesdeHooge I agree, the string is specific and your answer is nice, obvious (duh) and concise. Thank you

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.