Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Path manipulation in python

Tags:

python

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".

like image 483
RFV Avatar asked Dec 07 '22 20:12

RFV


2 Answers

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'
like image 114
brandizzi Avatar answered Dec 21 '22 23:12

brandizzi


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'
like image 24
Bakuriu Avatar answered Dec 21 '22 22:12

Bakuriu