2016-04-20 3 views
0

Ich versuche, durch ein Verzeichnis zu gehen und rekursiv durchsuchen drei Unterverzeichnisse in meinem übergeordneten Verzeichnis. Das wird funktionieren:Rekursivsuche mehrere Verzeichnisse mit os.walk()

aber es ist ziemlich klobig. Wie kann ich os.walk durch mehrere Unterverzeichnisse, ohne sie hart zu codieren?

+0

Warum Sie eine Ebene nicht höher starten? – jonrsharpe

+0

Wenn ich das tue, wird nur 'c: \ workspace \ Sandbar_Process \ csv_output \ CSVs' für mein' fPattern' gesucht. Es scheint, als ob es vergisst, dass es andere Ordner zu suchen gibt. –

Antwort

0

, wenn Sie nur die drei Ordner in r'c:\workspace\Sandbar_Process\csv_output' haben Sie aus diesem Ordner os.walk können, sonst können Sie den zusätzlichen Ordner in deiner ersten Iteration, wie diese

Fall 1 ohne zusätzliche Ordner

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

Fall 2, extra Ordner

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

Manipulationen an der dirnames Ausbeute von os.walk beeinflussen, wie y ou besuchen die Unterordner später

Blick, was die Dokumentation darüber gesagt

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

Wenn topdown ist True kann der Anrufer ändern die dirnames Liste in-Place (vielleicht mit Del- oder Slice-Zuweisung) und walk() wird nur in die Unterverzeichnisse recurse, deren Namen in dirnames bleiben; Dies kann verwendet werden, um die Suche zu beschneiden, eine bestimmte Reihenfolge des Besuchs aufzuerlegen, oder sogar walk() über Verzeichnisse, die der Anrufer erstellt oder umbenennt, bevor es wieder walk() wieder aufnimmt. Ändern dirname wenn topdown ist False hat keine Auswirkungen auf das Verhalten der Spaziergang, weil im Bottom-up-Modus die Verzeichnisse in dirnames generiert werden, bevor dirpath selbst generiert wird.

Sie können auch Ihre Funktion wie diese

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 

hier Sie den Ordner geben neu definieren Sie Ihre Funktion arbeiten möchten, dann brauchen Sie nur nennen es mit dem Ordner, den Sie möchten, oder definieren eine andere Funktion, die dieses mit diesen Ordnern so aufruft, dass Sie Ihren Code nicht ohne Notwendigkeit wiederholen.

Aditionally, wenn Sie immer in diesem Ordner arbeiten können Sie, dass in einer globalen Variablen wie diese

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

setzen und nur die Ordnernamen relativ zu diesem Ordner geben, und wenn man den absoluten Pfad tun müssen, etwas tun

os.path.join(WORKING_FOLDER, foldername) 

und eine Funktion wie dies zum Beispiel definieren

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 

und zum Beispiel nennen es als

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

Ofcourse sollten Sie wissen, dass das Material, das Sie auf Ihre Funktionen geben ändern in der Regel schlechte Praxis, so dass Ihre Funktion wirklich

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 

oder besser sein sollte noch als Generator

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) 

in beiden Fällen gibt es keine unerwünschten Änderungen und Sie können es verwenden, als

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 

hierfür die Generator-Version ist besser, weil Sie nicht Speicher mit Zwischenergebnissen verlieren