pythonic tree-walking idioms

Fredrik Lundh fredrik at pythonware.com
Thu May 17 03:50:09 EDT 2001


raskol at hushmail.com wrote:
> I've scoured the source of the standard 2.1 library and discovered
> os.path.walk()

os.path.walk is pretty unpythonic, imo [1].  using an iterator-style
"walker" object is usually both faster and more convenient.

an example:

From: Fredrik Lundh (fredrik at effbot.org)
Subject: Re: Find file functionality
Newsgroups: comp.lang.python
Date: 2000/11/19

/.../

a third alternative is to forget about walk, and use a directory
walker object instead.  here's an example from the eff-bot guide
to the standard library:

# os-path-walk-example-3.py
# from (the eff-bot guide to) The Python Standard Library
# http://www.pythonware.com/people/fredrik/librarybook.htm

import os

class DirectoryWalker:

    def __init__(self, directory):
        self.stack = [directory]
        self.files = []
        self.index = 0

    def __getitem__(self, index):
        while 1:
            try:
                file = self.files[self.index]
                self.index = self.index + 1
            except IndexError:
                # pop next directory from stack.  this raises
                # an IndexError if there's nothing more to do
                self.directory = self.stack.pop()
                self.files = os.listdir(self.directory)
                self.index = 0
            else:
                # got a filename
                fullname = os.path.join(self.directory, file)
                if os.path.isdir(fullname) and not os.path.islink(fullname):
                    # it's a directory; save it for later
                    self.stack.append(fullname)
                return fullname

for file in DirectoryWalker("."):
    print file
    if something(file):
        break

/.../

when you loop over this object, the __getitem__ function will be
called over and over again, until the object raises an IndexError.

(chances are that Python 2.2 will provide a better iterator inter-
face, which makes this a bit more efficient.  see PEP 234 for more
info [2]).

Cheers /F

1) a function that I have to look up in the reference documentation
everytime I want to use it cannot possibly be called pythonic ;-)

2) http://python.sourceforge.net/peps/pep-0234.html





More information about the Python-list mailing list