Функция iter() в Python — создание объекта-итератора
В этом уроке вы узнаете, как эффективно использовать встроенную функцию iter() в Python и создавать объект-итератор.
- Что такое функция iter() в Python?
- Примеры функции iter() в Python
- Вторая форма функции iter()
- Использование функции iter() в Python для проверки, является ли объект итерируемым
Что такое функция iter() в Python?
Функция iter() возвращает итератор данного объекта:
iter(object)
Функция iter() требует аргумента, который может быть итерацией или последовательностью. В общем, аргументом объекта может быть любой объект, поддерживающий протокол итерации или последовательности.
Когда вы вызываете функцию iter() для объекта, функция сначала ищет метод __iter__() этого объекта.
Если метод __iter__() существует, функция iter() вызывает его, чтобы получить итератор. В противном случае функция iter() будет искать метод __getitem__(). Если __getitem__() доступен, функция iter() создает объект-итератор и возвращает этот объект. В противном случае возникает исключение TypeError.
Следующая блок-схема иллюстрирует, как работает функция iter():
Примеры функции iter() в Python
В следующем примере определяется простой класс Counter и используется функция iter() для получения итератора объекта Counter:
class Counter: def __init__(self): self.__current = 0 counter = Counter() iterator = iter(counter)
Это вызовет TypeError, поскольку объект Counter не является итерируемым:
TypeError: 'Counter' object is not iterable
Следующий код добавляет метод __getitem__() в класс Counter:
class Counter: def __init__(self): self.current = 0 def __getitem__(self, index): if isinstance(index, int): self.current += 1 return self.current
Поскольку Counter реализует метод __getitem__(), который возвращает элемент на основе индекса, это последовательность.
Теперь вы можете использовать функцию iter(), чтобы получить итератор Counter:
counter = Counter() iterator = iter(counter) print(type(iterator))
Выход:
<class 'iterator'>
В этом случае Python создает объект-итератор и возвращает его. Следовательно, вы можете использовать объект итератора для итерации Counter:
for _ in range(1, 4): print(next(iterator))
Следующий код добавляет класс CounterIterator к классу Counter и реализует итерируемый протокол:
class Counter: def __init__(self): self.current = 0 def __getitem__(self, index): if isinstance(index, int): self.current += 1 return self.current def __iter__(self): return self.CounterIterator(self) class CounterIterator: def __init__(self, counter): self.__counter = counter def __iter__(self): return self def __next__(self): self.__counter.current += 1 return self.__counter.current
Как это работает.
- Класс Counter реализует метод __iter__(), который возвращает итератор. Возвращаемый итератор — это новый экземпляр CounterIterator.
- Класс CounterIterator поддерживает протокол итератора, реализуя методы __iter__() и __next__().
Если существуют оба метода __iter__() и __getitem__(), функция iter() всегда использует метод __iter__():
counter = Counter() iterator = iter(counter) print(type(iterator))
Выход:
<class '__main__.Counter.CounterIterator'> 1 2 3
В этом примере функция iter() вызывает метод __iter__() вместо метода __getitem__(). Вот почему вы видите CounterIterator в выходных данных.
Вторая форма функции iter()
Ниже показана вторая форма функции iter():
iter(callable, sentinel)
Iter(callable,sentinel) будет вызывать вызываемый объект при вызове метода next().
Он вернет значение, возвращаемое вызываемым объектом, или вызовет исключение StopIteration, если результат равен значению sentinel.
Давайте рассмотрим пример, чтобы понять, как работает iter(callable, Sentinel).
- Сначала определите функцию, которая возвращает замыкание:
def counter(): count = 0 def increase(): nonlocal count count += 1 return count return increase
Функция counter() возвращает замыкание. И замыкание возвращает новое целое число, начиная с единицы при вызове.
- Во-вторых, используйте функцию counter() для отображения чисел от 1 до 3:
cnt = counter() while True: current = cnt() print(current) if current == 3: break
Выход:
1 2 3
Чтобы сделать его более универсальным, вместо этого вы можете использовать итератор.
- В-третьих, определите новый итератор counter:
class CounterIterator: def __init__(self, fn, sentinel): self.fn = fn self.sentinel = sentinel def __iter__(self): return self def __next__(self): current = self.fn() if current == self.sentinel: raise StopIteration return current
Конструктор CounterIterator принимает вызываемый fn и sentinel.
Метод __next__() возвращает значение, возвращаемое вызываемым объектом(fn), или вызывает исключение StopIteration, если возвращаемое значение — sentinel.
Ниже показано, как использовать CounterIterator:
cnt = counter() iterator = CounterIterator(cnt, 4) for count in iterator: print(count)
Выход:
1 2 3
Вместо того, чтобы определять новый итератор каждый раз, когда вы хотите перебрать значения, возвращаемые вызываемым объектом, вы можете использовать функцию iter(callable, Sentinel):
cnt = counter() iterator = iter(cnt, 4) for count in iterator: print(count)
Выход:
1 2 3
Использование функции iter() в Python для проверки, является ли объект итерируемым
Чтобы определить, является ли объект итерируемым, вы можете проверить, реализует ли он метод __iter__() или __getitem__().
Однако вы можете использовать функцию iter() для проверки следующим образом:
def is_iterable(object): try: iter(object) except TypeError: return False else: return True
Если объект не реализует ни метод __iter__(), ни метод __getitem__(), функция iter() вызывает исключение TypeError.
Ниже показано, как использовать функцию is_iterable():
print(is_iterable([1, 2, 3])) print(is_iterable('Python iter')) print(is_iterable(100))
Выход:
True True False