Search code examples
pythoniteratordirectorysubdirectory

Iterating through directories throws non-iterator error


I tried exact code on this page to iterate through subdirectories. However, I am getting following error:

  File "dir_iterator.py", line 29, in <module>
    for x in it:
TypeError: iter() returned non-iterator of type 'iterdir'

Where is the problem and how can it be solved?

Note: I am using Python version 3.5.3 on Debian Stable Linux

Edit: As suggested by @DroidX86 in comments below, I am posting the code verbatim as copied from this link:

import os

class iterdir(object):
    def __init__(self, path, deep=False):
    self._root = path
    self._files = None
    self.deep = deep
    def __iter__(self):
    return self
    def next(self):
    if self._files:
        join = os.path.join
        d = self._files.pop()
        r = join(self._root, d)
        if self.deep and os.path.isdir(r):
        self._files += [join(d,n) for n in os.listdir(r)]
    elif self._files is None:
        self._files = os.listdir(self._root)
    if self._files:
        return self._files[-1]
    else:
        raise StopIteration


# sample:
#   a deep traversal of directories which starts with a vowel
#
it = iterdir('.')
for x in it:
    p = os.path.basename(x)
    it.deep = p[0].lower() in "aeiou"
    print x

Solution

  • The code is written for python2. For any reason, if you want it to run with python3, change def next: to def __next__: and print x to print(x). These two changes required to convert the python2 code in the link to python3.

    import os
    
    
    class iterdir(object):
        def __init__(self, path, deep=False):
            self._root = path
            self._files = None
            self.deep = deep
    
        def __iter__(self):
            return self
    
        def __next__(self):
            if self._files:
                join = os.path.join
                d = self._files.pop()
                r = join(self._root, d)
                if self.deep and os.path.isdir(r):
                    self._files += [join(d, n) for n in os.listdir(r)]
            elif self._files is None:
                self._files = os.listdir(self._root)
    
            if self._files:
                return self._files[-1]
            else:
                raise StopIteration
    
    
    # sample:
    #   a deep traversal of directories which starts with a vowel
    #
    it = iterdir('.')
    for x in it:
        p = os.path.basename(x)
        it.deep = p[0].lower() in "aeiou"
        print(x)