Проверка, является ли класс итеративным

У меня есть класс fib нижеприведенный. Это реализует __iter__ а также __next__, Это как итеративный, так и собственный итератор.

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))

Оператор печати возвращается FalseЯ бы ожидал, что он вернется True

1 ответ

Решение

Проверка, является ли объект итеративным, корректно, как вы сделали, выполняется с помощью:

isinstance(obj, collections.Iterable)

Проблема в том, что вы поставляете class в isinstance а не экземпляр. это False так как isinstance будет идти вперед и проверить, если type(fib) имеет __iter__ Метод определен:

type(fib).__iter__  # AttributeError

Это, конечно, не так. type(fib) является type который не определяет __iter__ метод.

Если вы предоставляете ему экземпляр, он правильно печатает True:

isinstance(fib(), Iterable)  # True

потому что смотрит в type(fib()) это найдет fib.__iter__,

В качестве альтернативы, кормление fib в issubclass выполняет аналогичную проверку, которая вместо этого принимает класс в качестве первого аргумента:

issubclass(fib, Iterable)    # True

Две дополнительные мелочи, на которые следует обратить внимание:

  • С помощью object поскольку явный базовый класс не нужен в Python 3 (хотя, если вы разрабатываете код, который работает как на Py2, так и на Py3, это хорошо.)
  • Согласно PEP 8, имена классов должны соответствовать соглашению CapWords, поэтому fib в идеале должен быть назван Fib,
Другие вопросы по тегам