Python程序炸毁后完成

时间:2018-10-30 03:41:12

标签: python pycharm

我遇到一个奇怪的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行之后有一个空白行。当最后一行没有行尾标记时,也会发生同样的事情。

无论是使用run命令从PyCharm内部运行还是从终端运行,都得到相同的结果。

您可能会从错误行看出来,该程序会生成动画。 (这是来自OpenAI体育馆的难题)。

由于程序在错误发生之前已完成,因此这不是灾难。但是我想了解发生了什么。

谢谢。

1 个答案:

答案 0 :(得分:1)

Python为类提供了__del__ dunder方法,这些类将在实例被垃圾回收时调用,if they're garbage collected.

使用时,__del__方法通常执行某种清理。

由于不经意间防止收集对象相当容易,因此请依靠__del__进行清理(而不是上下文管理器的__exit__或显式{{1 }}方法)。通常不建议这样做。

您的错误凸显了避免依赖.close()的另一个原因,但是:在关闭期间__del__将被调用,但是可能在其他依赖于它们的东西被释放后

关于注释中链接的github问题的拟议变通办法应该是有启发性的,因为它们都确保在仍依赖于清理的事物(例如__del__)定义时进行清理/尚未释放,例如:

sys.meta_path

try:
    del env
except ImportError:
    pass

和(可能,但效率或清晰程度低得多)

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