手动使用块生成会产生不同的内容

时间:2018-03-30 17:56:23

标签: python tensorflow contextmanager

假设我写了

with some_method()
    ...

我的印象是with命令首先在__enter__()返回的任何内容上调用some_method()方法。 (我相信some_method()返回的内容称为“上下文管理器”,这意味着它具有名为__enter__()__exit__()的方法。)

我尝试手动调用__enter__(),我得到的东西与我的预期不同。这个具体的例子出现在TensorFlow的上下文中,但我很确定它与TensorFlow没有任何关系。

import tensorflow as tf
x = tf.Session()
x.as_default().__enter__()
print(tf.get_default_session()) 

打印None

import tensorflow as tf
tf.Session().as_default().__enter__()
print(tf.get_default_session()) 

打印None,但

import tensorflow as tf
with tf.Session().as_default():
    print(tf.get_default_session()) 

打印<tensorflow.python.client.session.Session object at 0x114217a90>

我基本上发布了同样的问题here,但我错误地编辑了很多次,直到最后它还没有问到它开始问的问​​题。所以我只是在重新创造这个问题。

1 个答案:

答案 0 :(得分:2)

这可能是因为您丢弃了上下文管理器。很少有上下文管理器被设计为在__enter__之后被丢弃而不调用__exit__,如果你这样做,它们可能会表现得不可预测。当垃圾收集时,其中一些会自动调用等效的__exit__,有些则表现得更奇怪。

在这种特殊情况下,我相信tf.Session().as_default()最终会委托给generator-based context manager。当收集垃圾时,底层生成器会自动调用其close方法,这与调用上下文管理器的__exit__方法非常相似。