2016-10-06 3 views
2

Я посмотрел на переполнение стека всюду, но я не могу найти решение этой проблемы.Путь манипуляции в python

Учитывая, что у меня есть папка/файл в виде строки: "/path1/path2/path3/file" Как получить родительскую папку и ее родительскую папку. Другими словами, если я хочу пройти один уровень "/path1/path2/path3" или два уровня "/path1/path2", как я могу получить эти строковые значения из исходного пути строки в python?

Пожалуйста, обратите внимание, что я не просто хотите, чтобы части пути (другими словами, не список ['path1', 'path2', 'path3']), но вместо "/path1/path2/path3".

+2

Возможный дубликат [Как разбить путь дос в его компонентов в Python] (http://stackoverflow.com/questions/3167154/how-to-split-a-dos-path-in-its-components-in-python) – RedX

+0

'os.path.realpath (__ file __)' даст вам строку, содержащую путь к вашему файлу, а затем просто применяйте строковые манипуляции, чтобы сократить его. – zipa

+2

['os.path.dirname'] (https://docs.python.org/3.6/library/os.path.html#os.path.dirname)? и примените его 'n' раз, чтобы подняться на уровни' n' ... – Bakuriu

ответ

4

os.path.dirname() (doc) - это путь. Она возвращает каталог, который содержит объект, на который указывает путь:

>>> import os.path 
>>> os.path.dirname('/path1/path2/path3/file') 
'/path1/path2/path3' 

В этом случае, вы хотите «GrandParent» каталог, так что просто использовать функцию дважды:

>>> parent = os.path.dirname('/path1/path2/path3/file') 
>>> os.path.dirname(parent) 
'/path1/path2' 

Если вы хотите сделать это произвольное число раз, функция может быть полезна здесь:

def go_up(path, n): 
    for i in range(n): 
     path = os.path.dirname(path) 

    return path 

Вот некоторые примеры:

>>> 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' 
1

os.path.split сделают это за вас. Есть много других интересных функций.

+0

Разделите путь пути в пару, (head, tail), где tail является последним компонентом pathname, и голова - все, что до этого. Как я могу продвигать два или три уровня? – RFVenter

+1

@RFVenter Вызов функции несколько раз по результату? – RedX

0
'/'.join (originalPath.split ('/') [:-2]) 

Это займет у вас 2 уровня.

+1

Это может быть неудачно, например, если путь является путём Windows, использующим '' 'в качестве разделителя. – brandizzi

+0

Да, но вопрос был о пути Linux. Кстати, в качестве привычки я всегда конвертирую пути в пути Linux. Но признался, os.path - это общепринятый набор инструментов для работы. Мне нравится небольшой набор инструментов, хотя иногда я больше не могу найти молот ... –

+0

Его можно решить, заменив '/' на 'os.path.sep' –

0

os.path.dirname предоставляет родительский каталог.

+0

Это не то, о чем я просил. – RFVenter

+0

Да, это то, о чем вы просили. >>> 'os.path.dirname ("/path1/path2/path3/file ")' '/ path1/path2/path3' –

+0

Цитируя вопрос: 'или два уровня' –

2

дополнительно к всем остальным ответам вы также можете использовать функцию os.path.join с переменной os.path.pardir, которая обычно равна ...

>>> path = "some/random/path/to/process" 
>>> parent = os.path.pardir 
>>> grand_parent_path = os.path.join(path, parent, parent) 
>>> grand_parent_path 
'some/random/path/to/process\\..\\..' 

Если вы не хотите повторять parent несколько раз, вы можете использовать размноженный список:

>>> os.path.join(path, *([parent] * 3)) 
'some/random/path/to/process\\..\\..\\..' 

Результат довольно некрасиво, так что вы можете использовать функцию os.path.normpath, чтобы сделать его красивее :

>>> os.path.normpath(os.path.join(path, *([parent] * 3))) 
'some\\random' 

Важное примечание: Делая это, вы уверены, что ваш код является переносимым

2

Вы можете использовать модуль pathlib:

>>> path = pathlib.PurePath('/file1/file2/file3/file') 
>>> path.parts 
('/', 'file1', 'file2', 'file3', 'file') 
>>> os.path.join(*path.parts[:-2]) 
'/file1/file2' 

Так что просто положить path.parts[:-n] для n уровней вверх.

В качестве альтернативы вы можете использовать parents атрибут:

>>> 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') 

Так идти вверх n уровни просто использовать parents[n-1].

Чтобы преобразовать *Path объект в строку просто вызовите str на него:

>>> str(path) 
'/file1/file2/file3/file4/file5/file6' 
Смежные вопросы