_mgr = (f := open('file.txt')) # `f` is assigned here, even if `__enter__` fails
_mgr.__enter__() # the return value is discarded
exc = True
try:
try:
BLOCK
except:
# The exceptional case is handled here
exc = False
if not _mgr.__exit__(*sys.exc_info()):
raise
# The exception is swallowed if exit() returns true
finally:
# The normal and non-local-goto cases are handled here
if exc:
_mgr.__exit__(None, None, None)
而as形式是
^{pr2}$
即with (f := open(...))将f设置为open的返回值,而with open(...) as f将{}绑定到隐式__enter__()方法调用的返回值。在
TL;DR:这两个构造的行为并不相同,尽管这两个例子之间没有明显的区别。在
您几乎不应该在
with
语句中使用:=
,有时这是非常错误的。如果有疑问,当您需要with
块中的托管对象时,请始终使用with ... as ...
。在在
with context_manager as managed
中,managed
被绑定到context_manager.__enter__()
的返回值,而在with (managed := context_manager)
中,managed
绑定到context_manager
本身,__enter__()
方法调用的返回值是丢弃的。对于打开的文件,这种行为几乎是相同的,因为它们的__enter__
方法返回self
。在第一个节选是roughly analogous to
而
^{pr2}$as
形式是即}绑定到隐式
with (f := open(...))
将f
设置为open
的返回值,而with open(...) as f
将{__enter__()
方法调用的返回值。在现在,对于文件和流,如果成功,},因此这两种方法的行为几乎是相同的-唯一的区别是
file.__enter__()
将返回{__enter__
抛出异常。在赋值表达式通常可以代替} 是一个上下文管理器,它将返回mock对象。它的文档有以下示例:
as
起作用,这一事实是有欺骗性的,因为在许多类中,_mgr.__enter__()
返回的对象与self
不同。在这种情况下,赋值表达式的工作方式不同:分配上下文管理器,而不是托管对象。例如,^{现在,如果要编写为使用赋值表达式,则行为将不同:
mock_thing
现在绑定到上下文管理器,而不是新的模拟对象。在相关问题 更多 >
编程相关推荐