3

I have a class fib given below. It implements __iter__ and __next__. It is an iterable as well as its own iterator.

class fib(object):
    def __init__(self):
        self.prev = 0
        self.curr = 1

    def __iter__(self):
        return self

    def __next__(self):
        value = self.curr
        self.curr += self.prev
        self.prev = value
        return value


from collections import Iterable

print(isinstance(fib, Iterable))

The print statement returns False, I would expect it to return True

Dimitris Fasarakis Hilliard
  • 150,925
  • 31
  • 268
  • 253
liv2hak
  • 14,472
  • 53
  • 157
  • 270
  • 1
    `fib` is the *class*, not an instance. So you would use the subclass check `issubclass(fib, Iterable)`. Or you create an instance first: `isinstance(fib(), Iterable)` – That’s what you get for starting your class name with a lower case character ;) – poke Nov 21 '16 at 20:28
  • `fib` is not iterable. `fib` is a class whose instances are iterable. Trying to iterate over `fib` itself would be like trying to eat the concept of burgers. – user2357112 Nov 21 '16 at 20:58

1 Answers1

9

Checking if an object is iterable is correctly, as you've done, performed with:

isinstance(obj, collections.Iterable)

The problem here is you're supplying a class to isinstance and not an instance. It is False because isinstance will go ahead and check if type(fib) has an __iter__ method defined:

type(fib).__iter__  # AttributeError

This of course, isn't the case. type(fib) is type which doesn't define an __iter__ method.

If you supply an instance to it, it correctly prints True:

isinstance(fib(), Iterable)  # True

because looking in type(fib()) it will find fib.__iter__.

Alternatively, feeding fib to issubclass performs a similar check that, instead, takes a class as a first argument:

issubclass(fib, Iterable)    # True

Two extra minor things to point out:

  • Using object as an explicit base class is unnecessary in Python 3 (though, if you're developing code that runs on both Py2 and Py3, it is a good thing. (See Python class inherits object for more on this.)
  • According to PEP 8, class names should follow the CapWords convention, so fib should ideally be named Fib.
Dimitris Fasarakis Hilliard
  • 150,925
  • 31
  • 268
  • 253