How do I use os.scandir() to return DirEntry objects recursively on a directory tree?

Question:

Python 3.5’s os.scandir(path) function returns lightweight DirEntry objects that are very helpful with information about files. However, it only works for the immediate path handed to it. Is there a way to wrap it in a recursive function so that it visits all subdirectories beneath the given path?

Asked By: Mark

||

Answers:

You can scan recursively using os.walk(), or if you need DirEntry objects or more control, write a recursive function like scantree() below:

try:
    from os import scandir
except ImportError:
    from scandir import scandir  # use scandir PyPI module on Python < 3.5

def scantree(path):
    """Recursively yield DirEntry objects for given directory."""
    for entry in scandir(path):
        if entry.is_dir(follow_symlinks=False):
            yield from scantree(entry.path)  # see below for Python 2.x
        else:
            yield entry

if __name__ == '__main__':
    import sys
    for entry in scantree(sys.argv[1] if len(sys.argv) > 1 else '.'):
        print(entry.path)

Notes:

  • There are a few more examples in PEP 471 and in the os.scandir() docs.
  • You can also add various logic in the for loop to skip directories or files starting with '.' and that kind of thing.
  • You typically want follow_symlinks=false on the is_dir() calls in recursive functions like this, to avoid symlink loops.
  • On Python 2.x, replace the yield from line with:

    for entry in scantree(entry.path):
        yield entry
    
Answered By: Ben Hoyt
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.