os.path.commonprefix () та os.path.relpath () - ваші друзі:
>>> 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
'/'
Ви можете, таким чином, перевірити, чи є загальним префіксом один із шляхів, тобто якщо один із шляхів є загальним предком:
paths = […, …, …]
common_prefix = os.path.commonprefix(list_of_paths)
if common_prefix in paths:
…
Потім ви можете знайти відносні шляхи:
relative_paths = [os.path.relpath(path, common_prefix) for path in paths]
За допомогою цього методу ви навіть можете обробити більше двох шляхів і перевірити, чи всі шляхи знаходяться нижче одного з них.
PS : залежно від того, як виглядають ваші шляхи, ви можете спочатку виконати деяку нормалізацію (це корисно в ситуаціях, коли хтось не знає, чи завжди вони закінчуються на "/" чи ні, або якщо деякі шляхи відносні). Відповідні функції включають os.path.abspath () та os.path.normpath () .
PPS : як згадував Пітер Бріггс у коментарях, простий підхід, описаний вище, може провалитись:
>>> os.path.commonprefix(['/usr/var', '/usr/var2/log'])
'/usr/var'
незважаючи на те, що /usr/varце не звичайний префікс шляхів. Примушування всіх шляхів закінчуватися символом "/" перед викликом commonprefix()вирішує цю (специфічну) проблему.
PPPS : як згадується bluenote10, додавання косої риски не вирішує загальної проблеми. Ось його наступне питання: Як обійти помилковість Python's os.path.commonprefix?
PPPPS : починаючи з Python 3.4, ми маємо pathlib - модуль, що забезпечує середовище маніпуляції з більш безпечним шляхом. Я здогадуюсь, що загальний префікс набору шляхів можна отримати, отримавши всі префікси кожного шляху (з PurePath.parents()), взявши перетин усіх цих батьківських наборів та вибравши найдовший загальний префікс.
PPPPPS : Python 3.5 представив правильне рішення цього питання:, os.path.commonpath()який повертає дійсний шлях.