Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 270
Mark Avatar asked Oct 14 '15 20:10

Mark


People also ask

What does the OS Scandir () method return?

Return Type: This method returns an iterator of os. DirEntry objects corresponding to the entries in the given directory.

Is OS walk recursive?

One of the answers may be to use os. walk() to recursively traverse directories. The key here is to use os.

Is OS Listdir recursive?

listdir(path='. ') It returns a list of all the files and sub directories in the given path. We need to call this recursively for sub directories to create a complete list of files in given directory tree i.e.


1 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 
like image 102
Ben Hoyt Avatar answered Sep 26 '22 02:09

Ben Hoyt