从学习Python:
with语句的基本格式如下所示 方括号中的可选部分:
with expression [as variable]: with-block
假设此处
expression
返回支持该对象的对象 上下文管理协议(稍后将详细介绍此协议)。 如果存在可选的as子句,则此对象还可以返回将分配给名称variable
的值。请注意,
variable
未必分配结果expression
;expression
的结果是对象 支持上下文协议,可以分配variable
打算在声明中使用的其他内容。
expression
被评估为上下文管理器对象。
分配给variable
的内容是什么?引用只表示它不是上下文管理器对象。
variable
的赋值是否调用上下文管理器类的某个方法来生成分配给variable
的实际值?
感谢。
答案 0 :(得分:10)
从__enter__
返回的是什么。来自documentation on the __enter__
method of context managers:
contextmanager.__enter__()
输入运行时上下文并返回此对象或与运行时上下文相关的其他对象。 此方法返回的值使用此上下文管理器绑定到
as
语句的with
子句中的标识符。
(强调我的)
调用__enter__
的结果很可能是一个上下文管理器,规范中没有任何内容禁止这样做。它当然可以是与运行时上下文相关的另一个对象,如文档所述。
从__enter__
返回的对象可以一次又一次地用作上下文管理器。 file
objects,例如:
with open('test_file') as f1: # file.__enter__ returns self
with f1 as f2: # use it again, get __self__ back
print("Super context managing")
with f2 as f3, f1 as f4: # getting weird.
print("This can go on since f1.__enter__ returns f1")
print("f1.__exit__ has been called here, though :)")
print("f1 closed: {}".format(f1.closed))
并不是说前面的内容很有意义,只是为了说清楚。
答案 1 :(得分:9)
如果provides both __enter__
and __exit__
,您的对象可以充当上下文管理器。 __enter__
返回的对象绑定到您在as
语句的with
部分中指定的对象:
In [1]: class Foo:
...: def __enter__(self):
...: return 'hello'
...: def __exit__(self, *args):
...: pass
...:
In [2]: with Foo() as a:
...: print(a)
...:
hello