2017-12-15 3 views
2

나는 파이썬에서 find 명령처럼 작동하는 함수를 가지고있다. 그래서 기본적으로 깊이가 m_depth(최대 깊이)이되고 ignore_dirs으로 지정되면 디렉토리로 이동하지 않습니다. walk에있는 파일 목록을 반환합니다. 코드는 정말 간단하고 재귀를 사용합니다.wrapper와 같은 os find 함수에서 generator를 사용하는 방법?

그러나 많은 수의 파일 또는 심도의 경우 재귀가 시간이 걸리고 반환 할 때 목록이 커집니다. 어쨌든 발전기를 사용할 수 있는지 궁금합니다. 따라서 최소한 반복마다 메모리 소비가 적습니다.

yield 결과를 시도했지만 ignore_dirs이있을 때마다 종료되었습니다.

입니다 코드 내가 가진 :

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) 

답변

2

대답은 '예, 당신은 (단지 파이썬 3에서 사용 가능) yield from를 사용하여 재귀 발전기를 만들 수있다 :

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

문제를 함께' any (path ...의 ignore_sub_dir은'비디오 '디렉토리에 들어가기를 원하지 않는다고 가정하기 때문에'ignore_dirs'를'[videos ","some "]'로 전달할 것입니다. 소스 경로 아래에만 존재하는'비디오 '에 들어가기 위해서 * 오직 소스 경로 자체에'비디오'가 있다면 ... 처음 단계에서 돌아올 것입니다. 희망이 있습니다. 내 요점을 얻고 .... 비록 여러 가지 시나리오에 대한 코드를 단위 테스트했고 어떤 버그도 얻지 못했지만. –

+0

코드를 확인하고 알려 드리겠습니다! –

+0

내 테스트 케이스를 던지고있는 여분의 빈리스트가 리턴됩니다. 여분의 빈 목록을 반환하면 제거 할 수 있습니까? –

관련 문제