Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Checking if a class is iterable [duplicate]

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

like image 733
liv2hak Avatar asked May 14 '26 05:05

liv2hak


1 Answers

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.
like image 198
Dimitris Fasarakis Hilliard Avatar answered May 15 '26 19:05

Dimitris Fasarakis Hilliard



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!