🖥 Что такое итерабельный объект?



Итерабельный объект (в оригинальной терминологии – «iterable») – это объект, который может возвращать значения по одному за раз. Примеры: все контейнеры и последовательности (списки, строки и т.д.), файлы, а также экземпляры любых классов, в которых определён метод __iter__() или __getitem__(). Итерабельные объекты могут быть использованы внутри цикла for, а также во многих других случаях, когда ожидается последовательность (функции sum(), zip(), map() и т.д.).



Подробнее:



Рассмотрим итерируемый объект (Iterable). В стандартной библиотеке он объявлен как абстрактный класс collections.abc.Iterable:



class Iterable(metaclass=ABCMeta):



__slots__ = ()



@abstractmethod

def __iter__(self):

while False:

yield None



@classmethod

def __subclasshook__(cls, C):

if cls is Iterable:

return _check_methods(C, "__iter__")

return NotImplemented

У него есть абстрактный метод __iter__ который должен вернуть объект итератора. И метод __subclasshook__ который проверяет наличие у класса метод __iter__. Таким образом, получается, что итерируемый объект это любой объект который реализует метод __iter__



class SomeIterable1(collections.abc.Iterable):

def __iter__(self):

pass



class SomeIterable2:

def __iter__(self):

pass



print(isinstance(SomeIterable1(), collections.abc.Iterable))

# True

print(isinstance(SomeIterable2(), collections.abc.Iterable))

# True

Но есть один момент, это функция iter(). Именно эту функцией использует например цикл for для получения итератора. Функция iter() в первую очередь для получения итератора из объекта, вызывает его метод __iter__. Если метод не реализован, то она проверяет наличие метода __getitem__ и если он реализован, то на его основе создается итератор. __getitem__ должен принимать индекс с нуля. Если не реализован ни один из этих методов, тогда будет вызвано исключение TypeError.



from string import ascii_letters



class SomeIterable3:

def __getitem__(self, key):

return ascii_letters[key]



for item in SomeIterable3():

print(item)




@python_job_interview