Нужно некоторое объяснение на generator.close () - PullRequest
2 голосов
/ 09 февраля 2020

Я читаю python do c https://docs.python.org/3/reference/expressions.html о generator.close().

Мой перевод документации:

generator.close ()

Повышает GeneratorExit в точке, где была приостановлена ​​функция генератора.

  1. Если функция генератора затем корректно завершается:

    1.1 уже закрыт,
    1.2 или повышает GeneratorExit (не перехватывая исключение),

    close возвращается к своему абоненту.

  2. Если генератор выдает значение, RuntimeError повышается.

  3. Если генератор вызывает любое другое исключение, оно передается вызывающей стороне.

close() ничего не делает, если генератор уже вышел из-за исключения или нормального выхода.


Я не понимаю, как close() поведение соответствует документации.

>>> def echo(value=None):
...     print("Execution starts when 'next()' is called for the first time.")
...     try:
...         while True:
...             try:
...                 value = (yield value)
...             except Exception as e:
...                 value = e
...     finally:
...         print("Don't forget to clean up when 'close()' is called.")
...
>>> generator = echo(1)
>>> generator.close()
Don't forget to clean up when 'close()' is called.

Какое правило применяется к generator.close()? Я в замешательстве.

Мое понимание:

  1. generator.close() повышение GeneratorExit исключение
  2. GeneratorExit отслеживается except Exception as e: и l oop продолжает
  3. value = (yield value) выполняет
  4. в соответствии с правилом 2 выше, RuntimeError будет повышено.

Но это не Кажется, не так.

Пожалуйста, скажите мне, что происходит внутри.

1 Ответ

1 голос
/ 09 февраля 2020

GeneratorExit не наследуется от Exception, но от более фундаментального BaseException. Таким образом, он не перехватывается вашим except Exception блоком.

Так что ваше предположение 2 неверно. Генератор выходит изящно через случай 1.3, так как GeneratorExit не останавливается.

  1. GeneratorExit выбрасывается в (yield value).
  2. try: except Exception as e: проверяет, является ли ток Исключением является подкласс Exception. Поскольку это не так, он раскручивается.
  3. while True: раскручивается из-за текущего исключения.
  4. try: finally: раскручивается, выполняя свой блок finally:. Это приводит к отображению сообщения.
  5. Генератор завершает работу с текущим исключением, т.е. GeneratorExit.
  6. generator.close обнаруживает и подавляет GeneratorExit.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...