[Tutor] return values from function

Kent Johnson kent37 at tds.net
Sat Jul 30 13:51:50 CEST 2005


Jorge Louis De Castro wrote:
> Hi all,
> 
> I have the following code to traverse a directory structure from a given 
> path:
> 
> import os, fnmatch, re
> folders = []
> r = re.compile(r'file_filter') # msn_username is passed by the user
> 
> def browse(junk, dirpath, namelist):
>   for name in namelist:
>     if r.search(name):
>       folders.append(os.path.join(dirpath, name))
> 
> userbase = os.environ['USERPROFILE']
> # change directory to user profile folder
> os.chdir(userbase)
> os.path.walk(os.getcwd(), browse, None)
> 
> Now with the sample above I need global variables ("folders") to keep track 
> of the directories traversed. Ideally I'd like to either have the browse 
> function return a value that I could use or I'd like the ability to pass on 
> arguments to the browse function, which I can't seem to be able to.

os.path.walk() has a facility to pass a user argument to the visit() function. From the docs:
walk(path, visit, arg)
    Calls the function visit with arguments (arg, dirname, names) for each directory in the directory tree rooted at path (including path itself, if it is a directory).

Note that the third argument to walk(), is passed as the first argument to visit(). 
In your case, you should call
os.path.walk(os.getcwd(), browse, folders)

and define browse() as
def browse(folders, dirpath, namelist):

You could pass the regex as an argument also by making args the tuple (r, folders):
os.path.walk(os.getcwd(), browse, (r, folders))
def browse((r, folders), dirpath, namelist):

(Yes, you can do tuple unpacking in a def!)


You might also like to look at os.walk() which is easier to use. Instead of needing a callback, it generates a sequence that you use in a for loop. Your code would look like this:

import os, fnmatch, re
folders = []
r = re.compile(r'file_filter') # msn_username is passed by the user

userbase = os.environ['USERPROFILE']
# change directory to user profile folder
os.chdir(userbase)
for dirpath, dirnames, filenames in os.walk(os.getcwd()):
  for name in dirnames:
    if r.search(name):
      folders.append(os.path.join(dirpath, name))

(Note this version isn't quite the same as yours; it only finds folders matching the name. I'm guessing that is what you want.)

Kent



More information about the Tutor mailing list