在with-block之外使用with语句定义的变量?

Hei*_*nen 81 python

请考虑以下示例:

with open('a.txt') as f:
    pass
# Is f supposed to be defined here?
Run Code Online (Sandbox Code Playgroud)

我已经阅读了with语句和PEP-343的语言文档(2.7),但据我所知,他们在这个问题上没有说什么.

在CPython 2.6.5 f中似乎确实在with-block之外定义,但我宁愿不依赖可能改变的实现细节.

fuz*_*man 149

是的,上下文管理器将在with语句之外可用,并且不依赖于实现或版本.with语句不会创建新的执行范围.

  • 这是我认为最明确的解释,因此给出了公认的答案; 将给Alex和TokenMacGuy提供额外的有用信息. (3认同)

Sin*_*ion 27

with语法:

with foo as bar:
    baz()
Run Code Online (Sandbox Code Playgroud)

约为糖:

try:
    bar = foo.__enter__()
    baz()
finally:
    if foo.__exit__(*sys.exc_info()) and sys.exc_info():
        raise
Run Code Online (Sandbox Code Playgroud)

这通常很有用.例如

import threading
with threading.Lock() as myLock:
    frob()

with myLock:
    frob_some_more()
Run Code Online (Sandbox Code Playgroud)

上下文管理器可能不止一次使用.

  • 这又不是一个范围界定问题。范围将是相同的。但是,如果 foo.__exit__ 的实现将线程置于停止状态,那么除非 lock 有一个 __enter__ 来重新锁定它,否则第二条语句看起来不会对线程锁做任何有用的事情。 (2认同)

mik*_*iku 16

如果f是文件,它将在with语句外显示为关闭.

例如,这个

f = 42
print f
with open('6432134.py') as f:
    print f
print f
Run Code Online (Sandbox Code Playgroud)

会打印:

42
<open file '6432134.py', mode 'r' at 0x10050fb70>
<closed file '6432134.py', mode 'r' at 0x10050fb70>
Run Code Online (Sandbox Code Playgroud)

您可以在PEP-0343规范:'with'声明部分中找到详细信息.Python范围规则(可能会令人恼火)也适用f.


Ale*_*nor 11

在评论中回答Heikki的问题:是的,这个范围行为是python语言规范的一部分,并且适用于任何和所有兼容的Pythons(包括PyPy,Jython和IronPython).