【问题标题】:A Python walker that can ignore directories一个可以忽略目录的 Python walker
【发布时间】:2009-05-29 08:52:46
【问题描述】:

我需要一个文件系统遍历器,我可以指示它忽略遍历 我想保持不变的目录,包括所有子目录 在那个分支下面。 os.walk 和 os.path.walk 就是不这样做。

【问题讨论】:

    标签: python directory-walk


    【解决方案1】:

    实际上,os.walk 可能完全符合您的要求。假设我在ignore 中有一个要忽略的目录列表(可能是一组)。那么这应该工作:

    def my_walk(top_dir, ignore):
        for dirpath, dirnames, filenames in os.walk(top_dir):
            dirnames[:] = [ 
                dn for dn in dirnames 
                if os.path.join(dirpath, dn) not in ignore ]
            yield dirpath, dirnames, filenames
    

    【讨论】:

    • 我不知何故忘记了切片分配,我冒昧地将它添加到我的代码中。
    • 这是预期的做法,甚至在 os.path.walk() 的文档中也这么说。
    • 不,我的意思是完整的切片分配作为修改整个列表的一种方式,而不是您可以更改它的事实。
    • @Torsten Marek:您以“否”开始您的评论,而您的评论与 unwind 没有什么不同,他提到了文档,我引用:“当 topdown 为 True 时,调用者可以就地修改目录名列表(可能使用 del 或 slice 赋值)”。
    • @TZ...:我相信@Torsten 将@unwind 的评论视为对@Torsten 最初评论的回应,在这种情况下这是完全合理的(至少对我而言)。跨度>
    【解决方案2】:

    可以就地修改os.walk的返回值的第二个元素:

    [...] 调用者可以就地修改 dirnames 列表(可能使用 del 或 slice 赋值),并且 walk() 只会递归到名称保留在 dirnames 中的子目录;这可用于修剪搜索 [...]

    def fwalk(root, predicate):
        for dirpath, dirnames, filenames in os.walk(root):
            dirnames[:] = [d for d in dirnames if predicate(r, d)]
            yield dirpath, dirnames, filenames
    

    现在,您只需为子目录输入一个谓词:

    >>> ignore_list = [...]
    >>> list(fwalk("some/root", lambda r, d: d not in ignore_list))
    

    【讨论】:

      【解决方案3】:

      这是最好和最简单的解决方案。

      def walk(ignores):
          global ignore
          path = os.getcwd()
          for root, dirs, files in os.walk(path):
              for ignore in ignores:
                  if(ignore in dirs):
                      dirs.remove(ignore)
              print root
              print dirs
              print files
      walk(['.git', '.svn'])
      

      请记住,如果您从 dirs 中删除文件夹名称,os.walk 将不会对其进行探索。

      希望对你有帮助

      【讨论】:

        【解决方案4】:

        所以我做了这个home-roles walker函数:

        import os
        from os.path import join, isdir, islink, isfile
        
        def mywalk(top, topdown=True, onerror=None, ignore_list=('.ignore',)):
            try:
                # Note that listdir and error are globals in this module due
                # to earlier import-*.
                names = os.listdir(top)
            except Exception, err:
                if onerror is not None:
                    onerror(err)
                return
            if len([1 for x in names if x in ignore_list]):
                return 
            dirs, nondirs = [], []
            for name in names:
                if isdir(join(top, name)):
                    dirs.append(name)
                else:
                    nondirs.append(name)
        
            if topdown:
                yield top, dirs, nondirs
            for name in dirs:
                path = join(top, name)
                if not islink(path): 
                    for x in mywalk(path, topdown, onerror, ignore_list):
                        yield x
            if not topdown:
                yield top, dirs, nondirs
        

        【讨论】:

          猜你喜欢
          • 2018-04-22
          • 2011-03-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-07-10
          • 2017-02-21
          相关资源
          最近更新 更多