Getting a specific parent of a path by name

Tomerikoo :

I am trying to move my code from using os.path to using pathlib.Path.

I have a function that returns the full path of a specific parent that I look for by a constant name. As said, I am currently using os.path and strings for paths so right now this is done with regular-expressions.

What I want is for example for a constant parent = d to be able to get:

/a/b/c/d/e      -->  /a/b/c/d
/a/b/c/d/e/f    -->  /a/b/c/d
/root/a/b/c/d/e -->  /root/a/b/c/d

Note: as the example shows I don't want to rely on any fixed position from both sides.

I have tried 2 ways but both feels a bit clunky:

  1. Use the parts in order to find the correct parents element:

    >>> path = "/a/b/c/d/e/f"
    >>> parts = Path(path).parts
    >>> parent_index = len(parts) - 1 - parts.index('d') - 1
    >>> Path(path).parents[parent_index]
    PosixPath('/a/b/c/d')
    
  2. Use the parts and concatenate the relevant ones:

    >>> path = "/root/a/b/c/d/e"
    >>> parts = Path(path).parts
    >>> Path(*parts[:parts.index('d')+1])
    PosixPath('/root/a/b/c/d')
    

I would say that the second one seems reasonable, but still, my question is: Is there a better way to achieve this?


P.S. In case the part is not present in the path it is enough to raise an exception or any indicator (right now I wrap the code with index above with a try/except).

blhsing :

You can use a while loop instead to keep searching backwards for a parent of the given name:

path = Path("/a/b/c/d/e/f")
while path.name != 'd':
    path = path.parent
    assert path.name, 'No parent found with the given name'
print(path)

This outputs:

/a/b/c/d

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=408186&siteId=1