0

NOTE: Please, don't code it for me. I already have a home-rolled function to do what I describe below.

Is there a function in the standard Python library that will take an absolute path as argument, and return a tuple of all its "atomic" path components, after removing all redundant ones (e.g. ./), resolving bits like ../, etc.? For example, given the Unix path /s//pam/../ham/./eggs, the output should be

('/', 's', 'ham', 'eggs')

and given the Windows path C:\s\\pam\..\ham\.\eggs, the output should be

('C:', '\\', 's', 'ham', 'eggs')

Thanks!

kjo
  • 33,683
  • 52
  • 148
  • 265

2 Answers2

2

as close as you get (AFAIR) with the standard lib:

   >>> import os
   >>> help(os.path.split)
    Help on function split in odule ntpath:

    split(p)
        Split a pathname.
        Return tuple (head, tail) where tail is everything after the final slash.
        Either part may be empty.

this does not solve your usecase, but is trivially to extend so it does. For more info, see the comments.

ch3ka
  • 11,792
  • 4
  • 31
  • 28
  • 1
    It does not do what the OP asks. I think there's no such functionality in the standard library. – Stefano Borini May 10 '12 at 00:22
  • 1
    yes, it was proposed, but denied. os.path.split is the cloesest, that's why I mentioned it. for reference: http://bugs.python.org/issue11344 – ch3ka May 10 '12 at 00:26
0

There's no single function that will do what you want...primarily because what you're asking doesn't make any sense from a path-manipulation standpoint (because discarding .. changes the path in a meaningful fashion).

You could do something along the lines of:

[x for x in path.split(os.path.sep) if x not in ['.', '..']]

Which gives you:

>>> path='/s//pam/../ham/./eggs'
>>> [x for x in path.split(os.path.sep) if x not in ['.', '..']]
['', 's', '', 'pam', 'ham', 'eggs']

And:

>>> path=r'C:\s\\pam\..\ham\.\eggs'
>>> [x for x in path.split(os.path.sep) if x not in ['.', '..']]
['C:', 's', '', 'pam', 'ham', 'eggs']

(As long as os.path.sep is \).

It's obviously not exactly what you're looking for, but maybe it points the way in the right direction.

larsks
  • 277,717
  • 41
  • 399
  • 399
  • `os.path.normpath` performs precisely the kind of normalization I'm referring to; there's nothing non-sensical about it; e.g. `posixpath.normpath('/s//pam/../ham/./eggs')` returns `'/s/ham/eggs'`, etc. – kjo May 10 '12 at 01:23