[Python-Dev] os.path.walk() lacks 'depth first' option

Tim Peters tim.one@comcast.net
Mon, 21 Apr 2003 22:44:58 -0400


[Noah Spurrier]
>> I write these little directory/file filters quite often. I have
>> come across this problem of renaming the directories you are
>> traversing before.

[Martin v. L=F6wis]
> I still can't understand why you can't use os.path.walk for that.
> Did you know that you can modify the list that is passed to the
> callback, and that walk will continue to visit the elements in the =
list?

Let's spell it out.  Say the directory structure is like so:

a/
    b/
         c/
         d/
    e/

and we want to stick "x" at the end of each directory name.  The firs=
t thing
the callback sees is

    arg, "a", ["b", "e"]

The callback can rename b and e, and change the contents of the fname=
s list
to ["bx", "ex"] so that walk will find the renamed directories.  Etc.

This works:

"""
import os

def renamer(arg, dirname, fnames):
    for i, name in enumerate(fnames):
        if os.path.isdir(os.path.join(dirname, name)):
            newname =3D name + "x"
            os.rename(os.path.join(dirname, name),
                      os.path.join(dirname, newname))
            fnames[i] =3D newname   # crucial!

os.path.walk('a', renamer, None)
"""

It's certainly less bother renaming bottom-up; this works too (given =
the
last walk() generator implementation I posted):

"""
import os

for root, dirs, files in walk('a', topdown=3DFalse):
    for d in dirs:
        os.rename(os.path.join(root, d),
                  os.path.join(root, d + 'x'))
"""

A possible surprise is that neither of these renames 'a'.