Help me understand this iterator

Peter Otten __peter__ at web.de
Tue Oct 31 06:53:20 EST 2006


LaundroMat wrote:

> Hi,
> 
> I've found this script over at effbot
> (http://effbot.org/librarybook/os-path.htm), and I can't get my head
> around its inner workings. Here's the script:
> 
> import os
> 
> class DirectoryWalker:
>     # a forward iterator that traverses a directory tree
> 
>     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
>                 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):
>                     self.stack.append(fullname)
>                 return fullname
> 
> for file in DirectoryWalker("."):
>     print file
> 
> Now, if I look at this script step by step, I don't understand:
> - what is being iterated over (what is being called by "file in
> DirectoryWalker()"?);
> - where it gets the "index" value from;
> - where the "while 1:"-loop is quitted.

With 

dw = DirectoryWalker(".")

the for loop is equivalent to

index = 0 # internal variable, not visible from Python
while True:
    try: 
        file = dw[index] # invokes dw.__getitem__(index)
    except IndexError:
        break
    print file

This is an old way of iterating over a sequence which is only used when the
iterator-based approach

dwi = iter(dw) # invokes dw.__iter__()
while True:
    try:
        file = dwi.next()
    except StopIteration:
        break
    print file    

fails.

Peter



More information about the Python-list mailing list