2016-05-16 82 views
0

我正在搜索大型目录以将旧归档归类为特定顺序。我嵌入了一个递归调用的函数,当它找到一个文件路径匹配搜索条件的目录时,它将它添加到'found'字典fdict使用os.scandir停留在递归目录搜索中

预期的结果是,当在没有子目录的目录上调用该函数时,该函数完成时不执行任何操作并移回到一个级别。

运行时,它被卡在第一个目录中,它找不到子目录,只是递归调用当前目录进行搜索,陷入循环。

下面是代码摘要,任何洞察为什么它是循环将不胜感激。

def scan(queries, directory): 
    fdict = {} 
    def search(queries, directory, fdict): 
     for entry in os.scandir(directory): 
      if entry.is_dir(): 
       for x in queries: 
        if str(x) in entry.path: 
         fdict[str(x)] = entry.path 
         print("{} found and dicted".format(str(x))) 
        else: 
         search(queries, entry.path, fdict) 
      else: pass 
    search(queries, directory, fdict) 
    return fdict 
+0

请确保你没有关注[符号链接](https://docs.python.org/3/library/os.html#os.DirEntry.is_symlink)吗? –

回答

0

整个事情可以写为

import os 
# let qs be a list of queries [q] 
# root be the start dir 
for path, dirnames, filenames in os.walk(root): 
    for dirname in dirnames: 
     full_path = os.path.join(path, dirname) # optional (depends) 
     for q in qs: 
      if q in full_path: 
       # do whatever 

os.walk是递归的。您也可以执行一些set操作,以消除for q in qs。评论它是否不适合你。

+0

感谢os.walk的介绍。我以前没有使用它,并且正在使用scandir来获得速度,但是已经阅读过,似乎在3.5中使用了scandir算法来散步。你能否在你提到的'set'操作中快速完成? – wirrell

+0

@GeorgeWorrall谢谢。关于'set'操作,我暗指一个特殊情况。也就是说有一个函数'f',这样'query = f(full_path)'这意味着所有'full_path'都以同样的方式包含'query'。然后在full_paths中引入一个genexp fulls =(f(p)),然后'matches = queries.intersection(fulls)'。制作这些'set's bdw。 –

+0

这很清楚,再次感谢! – wirrell

0

好吧,原来问题出在for x in queries:声明中。

明显的循环是由不好的设计造成的,这意味着只有queries列表中的第一个值与调用else语句之前的entry.path相比,并且在当前entry.path上调用搜索函数。

一旦达到没有子目录的目录,它就会后退一个级别,并根据entry.path测试queries中的第二个条目。

尽管代码最终会产生所需的结果,但这种方法将需要绝对的年龄(在这种情况下,queries是一个4000值长的列表!),并给出了检查循环的外观。

如果有人遇到类似问题,以下是未来参考的更正代码。

def scan(queries, directory): 
    fdict = {} 
    def search(queries, directory, fdict): 
     for entry in os.scandir(directory): 
      if entry.is_dir(): 
       if entry.name in queries: 
        fdict[str(x)] = entry.path 
       else: 
        time.sleep(2) 
        search(queries, entry.path, fdict) 
      else: pass 
    search(queries, directory, fdict) 
    return fdict