手动实施 with block 会产生不同的东西
Implementing with block manually produces different things
假设我写
with some_method()
...
我的印象是 with
命令首先对 some_method()
返回的任何内容调用 __enter__()
方法。 (我相信 some_method()
返回的东西叫做 "context manager",这只是意味着它有方法叫做 __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()
最终会委托给 generator-based context manager。底层生成器在垃圾收集时自动调用其close
方法,这与调用上下文管理器的__exit__
方法非常相似。
假设我写
with some_method()
...
我的印象是 with
命令首先对 some_method()
返回的任何内容调用 __enter__()
方法。 (我相信 some_method()
返回的东西叫做 "context manager",这只是意味着它有方法叫做 __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()
最终会委托给 generator-based context manager。底层生成器在垃圾收集时自动调用其close
方法,这与调用上下文管理器的__exit__
方法非常相似。