2016-04-20 168 views
0

我想要遍歷目錄並遞歸搜索我的父目錄中的三個子目錄。這將工作:用os.walk遞歸搜索多個目錄()

def find_files(fPattern, list_to_append): 
    for root, dirnames, filenames in os.walk(r'c:\workspace\Sandbar_Process\csv_output\CSVs'): 
     for filename in fnmatch.filter(filenames, fPattern): 
      list_to_append.append(os.path.join(root, filename)) 
    for root, dirnames, filenames in os.walk(r'c:\workspace\Sandbar_Process\csv_output\No_Bath_CSVS'): 
     for filename in fnmatch.filter(filenames, fPattern): 
      list_to_append.append(os.path.join(root, filename)) 
    for root, dirnames, filenames in os.walk(r'c:\workspace\Sandbar_Process\csv_output\Two_Bar_CSVS'): 
     for filename in fnmatch.filter(filenames, fPattern): 
      list_to_append.append(os.path.join(root, filename)) 
    return list_to_append 

但它相當笨重。我如何通過多個子目錄而不必將其硬編碼到其中?

+0

你爲什麼不啓動一個水平? – jonrsharpe

+0

如果我這樣做,它只會搜索'fPattern'的'c:\ workspace \ Sandbar_Process \ csv_output \ CSVs'。它似乎忘記了還有其他文件夾要搜索。 –

回答

0

如果你只有在r'c:\workspace\Sandbar_Process\csv_output'的3個文件夾,你可以從該文件夾os.walk,否則,你可以在你的第一次迭代中刪除多餘的文件夾,這樣

情況1,沒有多餘的文件夾

for root, dirnames, filenames in os.walk(r'c:\workspace\Sandbar_Process\csv_output'): 
    for filename in fnmatch.filter(filenames, fPattern): 
     list_to_append.append(os.path.join(root, filename))  

情況2,額外的文件夾

my_folders = ['CSVs', 'No_Bath_CSVS', 'Two_Bar_CSVS'] 
first = True 
for root, dirnames, filenames in os.walk(r'c:\workspace\Sandbar_Process\csv_output'): 
    if first: 
     dirnames.clear() 
     dirnames.extend(my_folders) 
     first = False 
    for filename in fnmatch.filter(filenames, fPattern): 
     list_to_append.append(os.path.join(root, filename)) 

操作到dirnames產量由os.walk影響如何ÿ OU稍後訪問的子文件夾上

看什麼文件說,它

os.walk(top, topdown=True, onerror=None, followlinks=False)

自上而下True,調用者可以修改dirnames中列表就地(可能使用del或slice賦值),並且walk()只會遞歸到其名稱保留在dirnames中的子目錄;這可以用來修剪搜索,施加特定的訪問順序,或者甚至在它再次恢復walk()之前通知walk()關於呼叫者創建或重命名的目錄。修改dirnames當topdown爲False時,對walk的行爲沒有影響,因爲在自底向上模式下,dirnames中的目錄是在生成dirpath本身之前生成的。

您也可以重新定義你的函數類似這樣的

def find_files(fPattern, list_to_append, path): 
    for root, dirnames, filenames in os.walk(path): 
     for filename in fnmatch.filter(filenames, fPattern): 
      list_to_append.append(os.path.join(root, filename)) 
    return list_to_append 

在這裏你給你要在其中工作,以你的函數的文件夾,那麼你只需要在你需要的文件夾來稱呼它,或定義另一個功能是用這些文件夾調用這個文件夾,這樣你就不需要重複你的代碼。

的方法,另外,如果你總是該文件夾中工作,你可以把在一個全局變量這樣

WORKING_FOLDER = r'c:\workspace\Sandbar_Process\csv_output' 

,並只給相對於該文件夾的文件夾名稱,並在您需要的絕對路徑做東西做

os.path.join(WORKING_FOLDER, foldername) 

,並定義這樣的功能,例如

def my_work_in(fPattern, list_to_append, folders): 
    result = list_to_append 
    for foldername in folders: 
     result = find_files(fPattern, result , os.path.join(WORKING_FOLDER, foldername)) 
    return result 

並例如把它作爲

result = my_work_in(fPattern, [], ['CSVs', 'No_Bath_CSVS', 'Two_Bar_CSVS']) 

Ofcourse你應該知道,改變你給你的函數的東西通常是不好的做法,所以你的函數真的應該

def find_files(fPattern, path): 
    result = [] 
    for root, dirnames, filenames in os.walk(path): 
     for filename in fnmatch.filter(filenames, fPattern): 
      result.append(os.path.join(root, filename)) 
    return list_to_append 

或更好但作爲發電機

def find_files(fPattern, path): 
    for root, dirnames, filenames in os.walk(path): 
     for filename in fnmatch.filter(filenames, fPattern): 
      yield os.path.join(root, filename) 

在這兩種情況下都沒有不需要的修改你可以使用它作爲

result = [] 
result.extend(find_files(fPattern, r'c:\workspace\Sandbar_Process\csv_output\CSVs')) 
result.extend(find_files(fPattern, r'c:\workspace\Sandbar_Process\csv_output\No_Bath_CSVS')) 
result.extend(find_files(fPattern, r'c:\workspace\Sandbar_Process\csv_output\Two_Bar_CSVS')) 
print result 

該發電機版本更好,因爲你不與中介結果失去記憶