2017-12-15 9 views
2

Ich habe eine Funktion in Python, die wie find Befehl funktioniert. Also im Grunde wird es in die Tiefe gehen, bis es m_depth(maxdepth) erreicht und nicht in das Verzeichnis gehen, wenn es in ignore_dirs spezifiziert ist. Es wird eine Liste von Dateien zurückgegeben, die in einem walk gefunden wird. Der Code ist wirklich einfach und verwendet Rekursion.Wie Generator in os Funktion wie Wrapper verwenden?

Aber für eine große Anzahl von Dateien oder größere Tiefe dauert die Rekursion Zeit und die Liste wird größer, wenn sie zurückkehrt. Ich suche also, ob der Generator überhaupt verwendet werden kann, also zumindest der Speicherverbrauch bei jeder Iteration geringer ist?

Ich habe versucht mit yield ing das Ergebnis, aber dann ist es immer wenn eine ignore_dirs gefunden wird.

Dies ist der Code, den ich habe:

def find(source_d, m_depth, ignore_dirs): 
    ''' 
    This method does a recursive listing of files/directories from a given 
    path upto maximun recursion value provide as m_depth. 

    :param source_d: Given source path to start the recursion from 
    :param m_depth: Maximum recursion depth [determines how deep the method will traverse through the file system] 
    :param ignore_dirs: this paths will not be traversed. List of strings. 
    ''' 

    def helper_find(path, ignore_dirs, m_depth, curr_depth=1): 
     files = [] 
     if any(ignore_sub_dir == os.path.split(path)[-1] for ignore_sub_dir in ignore_dirs): 
      return [] 

     if m_depth < curr_depth: 
      return [] 

     else: 
      things = os.listdir(path) 

      for thing in things: 
       if(os.path.isdir(os.path.join(path, thing))): 
        files.extend(helper_find(os.path.join(path, thing), ignore_dirs, m_depth, curr_depth+1)) 

       else: 
        files.append(os.path.join(path, thing)) 

     return files 

    return helper_find(source_d, ignore_dirs, m_depth) 

Antwort

2

Die Antwort ja ist, können Sie eine rekursive Generator yield from unter Verwendung machen können (nur in Python 3):

def find(source_d, m_depth, ignore_dirs): 
    ''' 
    This method does a recursive listing of files/directories from a given 
    path upto maximun recursion value provide as m_depth. 

    :param source_d: Given source path to start the recursion from 
    :param m_depth: Maximum recursion depth [determines how deep the method will traverse through the file system] 
    :param ignore_dirs: this paths will not be traversed. List of strings. 
    ''' 
    def helper_find(path, ignore_dirs, m_depth, curr_depth=1): 
     if not any(ignore_sub_dir == os.path.split(path)[-1] for ignore_sub_dir in ignore_dirs)and m_depth >= curr_depth: 

      things = os.listdir(path) 

      for thing in things: 
       if(os.path.isdir(os.path.join(path, thing))): 
        yield from helper_find(os.path.join(path, thing), ignore_dirs, m_depth, curr_depth+1) 

       else: 
        yield os.path.join(path, thing) 

    return helper_find(source_d, ignore_dirs, m_depth) 
+0

Das Problem mit ' Any (ignore_sub_dir in path ... 'nehme an, ich möchte nicht in' videos' dir gehen. Also werde ich 'ignore_dirs' als' ["videos", "einige"] '' übergeben. Jetzt will ich nicht in 'videos' zu gehen, die nur unter dem Quellpfad * vorhanden sind * Was ist, wenn der Quellpfad selbst' videos' enthält, dann wird er im ersten Schritt zurückkommen Ich bekomme meinen Punkt ... Obwohl ich meinen Code für verschiedene Szenarien getestet habe und ich keinen Bug bekommen habe. –

+0

Ich werde Ihren Code einchecken und Sie wissen lassen! –

+0

Es gibt einige zusätzliche leere Liste zurück, die mein Testcase auswirft. Kann die Rückgabe einer zusätzlichen leeren Liste entfernt werden? –

Verwandte Themen