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
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:
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.)fib should ideally be named Fib. If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With