Программа Python взрывается после окончания - PullRequest
0 голосов
/ 30 октября 2018

Я получаю странную ошибку Python. Я выполняю файл, который выглядит следующим образом.

if __name__ == '__main__':
    MyClass().main()
    print('Done 1')
    print('Done 2')

Предыдущее успешно выполнено. Но когда я изменяю это на это, я получаю странный результат.

if __name__ == '__main__':
    myObject = MyClass()
    myObject.main()
    print('Done 1')
    print('Done 2')

Вывод выглядит следующим образом.

Done 1
Done 2
Exception ignored in: <function Viewer.__del__ at 0x0000021569EF72F0> 
Traceback (most recent call last):
  File "C:\...\lib\site-packages\gym\envs\classic_control\rendering.py", line 143, in __del__
  File "C:\...\lib\site-packages\gym\envs\classic_control\rendering.py", line 62, in close
  File "C:\...\lib\site-packages\pyglet\window\win32\__init__.py", line 305, in close
  File "C:\...\lib\site-packages\pyglet\window\__init__.py", line 770, in close
ImportError: sys.meta_path is None, Python is likely shutting down

Process finished with exit code 0

После последней строки print есть пустая строка. То же самое происходит, когда в последней строке нет маркера конца строки.

Я получаю тот же результат, независимо от того, запускаю ли я его из PyCharm с помощью команды run или из терминала.

Как вы, вероятно, можете сказать по ошибочным строкам, программа генерирует анимацию. (Это проблема с полюсом тележки в спортзале OpenAI.)

Поскольку программа завершает работу до ошибки, это не катастрофа. Но я бы хотел понять, что происходит.

Спасибо.

1 Ответ

0 голосов
/ 30 октября 2018

Python предоставляет метод __del__ dunder для классов, которые будут вызываться при сборке мусора, , если сборщик мусора .

При использовании метод __del__ обычно выполняет некоторую очистку.

Из-за того, что довольно легко непреднамеренно предотвратить сбор объекта, полагается на __del__ для выполнения очистки (вместо, скажем, __exit__ диспетчера контекста или явного .close() метода), как правило, не рекомендуется.

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

из-за других вещей, на которые она опирается

Предлагаемые обходные пути по проблеме github, связанные в комментариях, должны быть поучительными, поскольку все они гарантируют, что очистка выполняется в то время, когда вещи, на которые опирается очистка (например, sys.meta_path), все еще находятся в определенном / не определенном состоянии. еще не освобожден, например:

try:
    del env
except ImportError:
    pass

и

env = gym.make('CartPole-v0')
...
env.env.close()

и (вероятно, но гораздо менее эффективно или ясно)

import gc; gc.collect()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...