我遇到一个问题,即未调用Tensorflow会话对象的Python析构函数。
考虑以下在Python 3.4+上运行的代码:
<td>
(我们从Monkey patch __del__ to new function获得了monkeypatching代码。您还可以通过在virtualenv中安装TensorFlow并直接编辑源代码https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/client/session.py#L686来重现此代码)
当我们注释掉import tensorflow as tf
# CODE THAT CHANGES BEHAVIOR
datashape = [1]
y = tf.ones(shape=datashape)
sess = tf.Session()
sess.delete2 = sess.__del__
def override(p, methods):
oldType = type(p)
newType = type(oldType.__name__ + "_Override", (oldType,), methods)
p.__class__ = newType
def p(self):
print("__del__ called")
self.delete2()
def monkey(x):
override(x, {"__del__": p})
monkey(sess)
print("Deleting sess:")
后面的两行时,在解释器退出时,我们看到# CODE THAT CHANGES BEHAVIOR
已打印。
当我们省略这两行时,看不到__del__ called
打印出来。
另外,如果将所有代码包装在一个函数中(例如,使用__del__ called
约定),我们也会看到__main__
被调用。
注意:根据Why aren't destructors guaranteed to be called on interpreter exit?中公认的答案,Python 3.4+保证总是在解释器出口处调用析构函数。
为什么会出现这种现象,我们如何解决?