假设我写
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 ,但我犯了太多次编辑它的错误,直到最后它并没有问它开始问的是什么。所以我只是重新提出这个问题。
最佳答案
这可能是因为您放弃了上下文管理器。很少有上下文管理器被设计为在 __enter__
之后被丢弃,而不调用 __exit__
,如果您这样做,它们的行为可能会不可预测。其中一些在垃圾收集时会自动调用相当于 __exit__
的函数,而另一些则以更奇怪的方式运行。
在这种特殊情况下,我相信 tf.Session().as_default()
最终委托(delegate)给 generator-based context manager 。底层生成器在垃圾收集时自动调用其 close
方法,这与调用上下文管理器的 __exit__
方法非常相似。
关于python - 手动使用 block 实现会产生不同的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49579103/