在 with 语句中或之前评估和分配表达式
Evaluate and assign expression in or before with statement
如果我是正确的,with
语句不会为 with
语句引入局部作用域。
这些是学习中的例子 Python:
with open(r'C:\misc\data') as myfile:
for line in myfile:
print(line)
...more code here...
和
lock = threading.Lock() # After: import threading
with lock:
# critical section of code
...access shared resources...
第二个例子是否等同于下面以类似于第一个例子的方式重写?
with threading.Lock() as lock:
# critical section of code
...access shared resources...
它们有什么区别?
第一个例子是否等同于下面以类似于第二个例子的方式重写?
myfile = open(r'C:\misc\data')
with myfile:
for line in myfile:
print(line)
...more code here...
它们有什么区别?
Here's a good explanation。我将解释关键部分:
The with
statement could be thought of like this code:
set things up
try:
do something
finally:
tear things down
Here, “set things up” could be opening a file, or acquiring some sort of external resource, and “tear things down” would then be closing the file, or releasing or removing the resource. The try-finally construct guarantees that the “tear things down” part is always executed, even if the code that does the work doesn’t finish.
当 with
进入上下文时,它会调用上下文管理器对象上的挂钩,称为 __enter__
,并且可以选择将该挂钩的 return 值分配给一个名称使用 as <name>
。许多上下文管理器 return self
来自他们的 __enter__
钩子。如果他们这样做,那么您确实可以在单独的行上创建上下文管理器或使用 as
.
捕获对象之间做出选择。
在您的两个示例中,只有从 open()
编辑的文件对象 return 具有 return 与 self
的 __enter__
挂钩。对于 threading.Lock()
、__enter__
return 与 Lock.acquire()
相同的值,因此 布尔值 ,而不是锁定对象本身。
您需要查找明确的文档来证实这一点;然而,这并不总是那么清楚。对于 Lock
个对象,relevant section of the documentation 状态:
All of the objects provided by this module that have acquire()
and release()
methods can be used as context managers for a with
statement. The acquire()
method will be called when the block is entered, and release() will be called when the block is exited.
对于文件对象,IOBase
documentation 相当模糊,您必须从示例中推断文件对象是 returned.
要记住的主要事情是 returning self
不是强制性的 ,也不是总是需要的。上下文管理器完全可以 return 其他东西。例如,许多数据库连接对象是上下文管理器,可让您管理事务(自动回滚或提交,具体取决于是否存在异常),其中输入 returns 一个绑定到连接的新游标对象。
明确地说:
对于您的 open()
示例,这两个示例的所有意图和目的完全相同。两者都调用 open()
,如果没有引发异常,您最终会引用名为 myfile
的文件对象。在这两种情况下,文件对象都将在 with
语句完成后关闭。该名称在 with
语句完成后继续存在。
有区别,但主要是技术上的。对于 with open(...) as myfile:
,创建文件对象,调用它的 __enter__
方法,然后绑定 myfile
。对于myfile = open(...)
情况,myfile
先绑定,__enter__
后调用。
对于您的 with threading.Lock() as lock:
示例,使用 as lock
会将 lock
设置为 True
(锁定总是成功或以这种方式无限期阻塞) .这不同于 lock = threading.Lock()
情况,其中 lock
绑定到锁对象。
如果我是正确的,with
语句不会为 with
语句引入局部作用域。
这些是学习中的例子 Python:
with open(r'C:\misc\data') as myfile:
for line in myfile:
print(line)
...more code here...
和
lock = threading.Lock() # After: import threading
with lock:
# critical section of code
...access shared resources...
第二个例子是否等同于下面以类似于第一个例子的方式重写?
with threading.Lock() as lock:
# critical section of code
...access shared resources...
它们有什么区别?
第一个例子是否等同于下面以类似于第二个例子的方式重写?
myfile = open(r'C:\misc\data')
with myfile:
for line in myfile:
print(line)
...more code here...
它们有什么区别?
Here's a good explanation。我将解释关键部分:
The
with
statement could be thought of like this code:set things up try: do something finally: tear things down
Here, “set things up” could be opening a file, or acquiring some sort of external resource, and “tear things down” would then be closing the file, or releasing or removing the resource. The try-finally construct guarantees that the “tear things down” part is always executed, even if the code that does the work doesn’t finish.
当 with
进入上下文时,它会调用上下文管理器对象上的挂钩,称为 __enter__
,并且可以选择将该挂钩的 return 值分配给一个名称使用 as <name>
。许多上下文管理器 return self
来自他们的 __enter__
钩子。如果他们这样做,那么您确实可以在单独的行上创建上下文管理器或使用 as
.
在您的两个示例中,只有从 open()
编辑的文件对象 return 具有 return 与 self
的 __enter__
挂钩。对于 threading.Lock()
、__enter__
return 与 Lock.acquire()
相同的值,因此 布尔值 ,而不是锁定对象本身。
您需要查找明确的文档来证实这一点;然而,这并不总是那么清楚。对于 Lock
个对象,relevant section of the documentation 状态:
All of the objects provided by this module that have
acquire()
andrelease()
methods can be used as context managers for awith
statement. Theacquire()
method will be called when the block is entered, and release() will be called when the block is exited.
对于文件对象,IOBase
documentation 相当模糊,您必须从示例中推断文件对象是 returned.
要记住的主要事情是 returning self
不是强制性的 ,也不是总是需要的。上下文管理器完全可以 return 其他东西。例如,许多数据库连接对象是上下文管理器,可让您管理事务(自动回滚或提交,具体取决于是否存在异常),其中输入 returns 一个绑定到连接的新游标对象。
明确地说:
对于您的
open()
示例,这两个示例的所有意图和目的完全相同。两者都调用open()
,如果没有引发异常,您最终会引用名为myfile
的文件对象。在这两种情况下,文件对象都将在with
语句完成后关闭。该名称在with
语句完成后继续存在。有区别,但主要是技术上的。对于
with open(...) as myfile:
,创建文件对象,调用它的__enter__
方法,然后绑定myfile
。对于myfile = open(...)
情况,myfile
先绑定,__enter__
后调用。对于您的
with threading.Lock() as lock:
示例,使用as lock
会将lock
设置为True
(锁定总是成功或以这种方式无限期阻塞) .这不同于lock = threading.Lock()
情况,其中lock
绑定到锁对象。