Убирайся на перерыв oop - PullRequest
       18

Убирайся на перерыв oop

3 голосов
/ 05 апреля 2020

Можете ли вы создать итерацию в python, которая выполняет код очистки при выходе из l oop? Что-то вроде:

from random import randint

class Iterable:
    def __iter__(self):
        return self
    def __next__(self):
        return randint(1, 10)
    def __iterclose__(self):
        print("Clean up code")

for x in Iterable():
    if x < 5:
        break

# Prints "Clean up code"

Ответы [ 2 ]

0 голосов
/ 05 апреля 2020

Как я уже сказал в комментарии:

При завершении итерации вы должны вызвать исключение StopIteration, на этом этапе вы уже должны знать, что должны выполнить очистку, иначе этот итератор будет запущен навсегда.

Также итераторы и итерируемые - это разные вещи, от беглого python book:

итератор

Любой объект, который реализует next метод без аргументов, который возвращает следующий элемент в серии или вызывает StopIteration, когда больше нет элементов. Итераторы Python также реализуют метод iter , поэтому они также могут быть повторяемыми

Где:

iterable Любой объект, из которого построена iter- в функции можно получить итератор. Объекты, реализующие метод iter , возвращающий итератор, являются итеративными.

Поэтому итератор должен знать, когда он закончится. Надеемся, этот код прояснит ситуацию:

from random import randint

class MyIterator:
  def __init__(self, n):
    self.n = n
    self.i = 0

  def __iter__(self):
    return self

  def __next__(self):
    if self.i < self.n:
      self.i += 1
      return randint(1, 10)
    else:
      print("doing cleanup")
      #do the clean up you want
      raise StopIteration()

class MyIterable:
    def __init__(self, n):
      self.n = n
    def __iter__(self):
        return MyIterator(self.n)

for x in MyIterable(5):
  print(x)

Вывод:

4
9
7
5
1
doing cleanup

Примечание: Здесь лучше делать что-то, используя функцию генератора или выражение, но это сделает вещи более различимыми.

0 голосов
/ 05 апреля 2020

Я думаю, чтобы воспользоваться итерируемым протоколом, вы должны позволить вашему Iterable получить контроль над условием остановки. Как насчет этого:


from random import randint


class Iterable:

    def __init__(self, max):
        self.i = 0
        self.max = max

    def __iter__(self):
        return self

    def __next__(self):
        self.i += 1
        if self.i > self.max:
            self.cleanup()
            raise StopIteration
        return randint(1, 10)

    def cleanup(self):
        print("Clean up code")


for x in Iterable(5):
    print(x)
...