os.path.commonprefix () i os.path.relpath () to Twoi przyjaciele:
>>> print os.path.commonprefix(['/usr/var/log', '/usr/var/security'])
'/usr/var'
>>> print os.path.commonprefix(['/tmp', '/usr/var']) # No common prefix: the root is the common prefix
'/'
Możesz więc sprawdzić, czy wspólny prefiks jest jedną ze ścieżek, tj. Czy jedna ze ścieżek jest wspólnym przodkiem:
paths = […, …, …]
common_prefix = os.path.commonprefix(list_of_paths)
if common_prefix in paths:
…
Następnie możesz znaleźć ścieżki względne:
relative_paths = [os.path.relpath(path, common_prefix) for path in paths]
Za pomocą tej metody można nawet obsłużyć więcej niż dwie ścieżki i sprawdzić, czy wszystkie ścieżki znajdują się poniżej jednej z nich.
PS : w zależności od tego, jak wyglądają Twoje ścieżki, możesz najpierw zechcieć przeprowadzić pewną normalizację (jest to przydatne w sytuacjach, gdy nie wiadomo, czy zawsze kończą się znakiem „/”, czy też nie, lub jeśli niektóre ścieżki są względne). Odpowiednie funkcje obejmują os.path.abspath () i os.path.normpath () .
PPS : jak wspomniał w komentarzach Peter Briggs, proste podejście opisane powyżej może się nie powieść:
>>> os.path.commonprefix(['/usr/var', '/usr/var2/log'])
'/usr/var'
mimo że nie/usr/var jest to wspólny prefiks ścieżek. Wymuszenie przed wywołaniem wszystkich ścieżek kończących się znakiem „/” rozwiązuje ten (konkretny) problem.commonprefix()
PPPS : jak wspomniano w bluenote10, dodanie ukośnika nie rozwiązuje ogólnego problemu. Oto jego kolejne pytanie: Jak obejść błąd związany z os.path.commonprefix w języku Python?
PPPPS : począwszy od Pythona 3.4, mamy pathlib , moduł zapewniający bardziej rozsądne środowisko do manipulacji ścieżkami. Myślę, że wspólny prefiks zestawu ścieżek można uzyskać, pobierając wszystkie prefiksy każdej ścieżki (z PurePath.parents()), biorąc przecięcie wszystkich tych zestawów nadrzędnych i wybierając najdłuższy wspólny prefiks.
PPPPPS : Python 3.5 wprowadził poprawne rozwiązanie tego pytania :,os.path.commonpath() które zwraca prawidłową ścieżkę.