2012-05-30 49 views
2

所有父文件夾這個屬於問一個問題來回答它着想的範疇(儘管我會接受的答案,如果他們比我好)顯示在Python

如何做一個打印出來的絕對路徑給定子文件夾的所有父文件夾。鑑於以下

'/home/marx/Documents/papers/communism' 

返回

[ 
    '/', 
    '/home', 
    '/home/marx', 
    '/home/marx/Documents', 
    '/home/marx/Documents/papers', 
    '/home/marx/Documents/papers/communism' 
] 

注意的代碼沒有檢查該文件存在,但我不希望虛假輸出是否有尾隨斜線,周邊空格或兩個並排正斜槓

回答

4

使用模塊os.path中的功能 - 它與平臺無關,即相同的代碼可用於Windows路徑(在Windows安裝中運行時)。

使用os.path.normpath()可以很好地處理重複和尾隨路徑分隔符以及包含「..」的路徑。使用此代替os.path.abspath(),因爲從非絕對路徑上的不同目錄運行時會得到不同的結果。

import os.path 

def get_parents(path): 
    parents = [] 
    path = os.path.normpath(path) 
    while path: 
     parents.insert(0, path) 
     if path == '/': 
      path = '' 
     else: 
      path = os.path.dirname(path) 

    return parents 

>>> print get_parents('') 
['.'] 
>>> print get_parents('/') 
['/'] 
>>> print get_parents('/////') 
['/'] 
>>> print get_parents('/home/marx/Documents/papers/communism') 
['/', '/home', '/home/marx', '/home/marx/Documents', '/home/marx/Documents/papers', '/home/marx/Documents/papers/communism'] 
>>> print get_parents('/home/marx/Documents/papers/communism/') 
['/', '/home', '/home/marx', '/home/marx/Documents', '/home/marx/Documents/papers', '/home/marx/Documents/papers/communism'] 
>>> print get_parents('////home/marx////Documents/papers/communism/////') 
['/', '/home', '/home/marx', '/home/marx/Documents', '/home/marx/Documents/papers', '/home/marx/Documents/papers/communism'] 
>>> print get_parents('home/marx////Documents/papers/communism/////') 
['home', 'home/marx', 'home/marx/Documents', 'home/marx/Documents/papers', 'home/marx/Documents/papers/communism'] 
>>> print get_parents('/home/marx////Documents/papers/communism/////../Das Kapital/') 
['/', '/home', '/home/marx', '/home/marx/Documents', '/home/marx/Documents/papers', '/home/marx/Documents/papers/Das Kapital'] 
>>> print get_parents('/home/marx////Documents/papers/communism/////../Das Kapital/') 
['/', '/home', '/home/marx', '/home/marx/Documents', '/home/marx/Documents/papers', '/home/marx/Documents/papers/Das Kapital'] 
>>> print get_parents('/home/marx////Documents/papers/communism/////../Das Kapital/../../../../../../') 
['/'] 
+0

這是所有答案中最好的。小記,至少在Mac上(在家裏沒有linux),前導或尾隨空格導致奇怪的行爲。 – puk

+0

@puk:奇怪的行爲?在* nix空格中是一個有效的文件/目錄名,例如''/ a/b/c/d''是有效的。它分解爲'['','/ a','/ a/b','/ a/b/c','/ a/b/c/d'] – mhawke

+0

@puk:的空間作爲要求,但它們的確可以是有效的名稱。如果你真的想要它們,使用'/ a/b/c/d'.strip()。 – lgautier

-1

這個最小的程序塊工作正常,除了如果有多個並排正斜槓失敗。

#!/usr/bin/env python 

import os 

def getParents (path):  
    parents = [ path ] 
    while path != '/': 
     path = os.path.dirname (path) 
     parents.append (path) 
    parents.reverse() 
    return parents 

if __name__ == '__main__': 
    print getParents ('/home/marx/Documents/papers/communism') 
+2

'global os'?真? –

+0

@EliBendersky我不需要它嗎?我記得它在一段時間內會造成問題 – puk

+0

@puk不,你不需要它。 – jamylak

0
import os; 
import sys; 

def stripDoubleSlash(fullPath): 
    if fullPath: 
     replaced = fullPath.replace('//','/'); 
     if replaced.find('//') >= 0: 
      return stripDoubleSlash(replaced); 
     else: 
      return replaced; 
    return fullPath; 
def printAllParents(fullPath): 
    tokens = stripDoubleSlash(fullPath).rstrip('/').split('/'); 
    for i in xrange(0,len(tokens)): 
     if i == 0 and not fullPath[0] == '/': 
      print tokens[0]; 
     else: 
      print '/'.join(tokens[0:i])+'/'+tokens[i]; 
if __name__ == '__main__': 
    printAllParents(sys.argv[1] if len(sys.argv) > 1 else '/home/marx/Documents/papers/communism/'); 
1

應該處理大多一切。

import os 

def parents(x, sep = os.path.sep): 
    x = os.path.normpath(x) 
    if x == sep: # bail out if only leading '/'s 
     return [x, ] 
    elements = x.split(sep) 
    res = list(sep.join(elements[:i]) for i in range(1, len(elements)+1)) 
    res[0] = sep # fix leading/
    return res 



>>> x = '/home/marx/Documents///papers/communism/' 
>>> parents(x) 
['/', 
'/home', 
'/home/marx', 
'/home/marx/Documents', 
'/home/marx/Documents/papers', 
'/home/marx/Documents/papers/communism'] 

編輯:手柄正確 「父母( '////')」

編輯:通過添加一個可選參數 「SEP」 簡化代碼,並使用normpath()(如在其他答案中指出的那樣)

+0

看起來比我的版本更乾淨。我明天會試一試。如果有效,我會接受這個 – puk

+0

不是地球破碎,但是父母失敗('////')' – puk

+0

是的。我編輯了該功能來修復它。 – lgautier