Переменная, определенная с помощью оператора with, доступного за пределами блока with?


рассмотрим следующий пример:

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

Я прочитал языковые документы (2.7) для with-statement, а также PEP-343, но, насколько я могу судить, они ничего не говорят по этому вопросу.

В CPython 2.6.5 f похоже, что он определен вне блока С-block, Но я бы предпочел не полагаться на детали реализации, которые могут измениться.

4 67

4 ответа:

да, менеджер контекста будет доступен вне оператора with, и это не зависит от реализации или версии. с заявлениями не создать новую область выполнения.

the with синтаксис:

with foo as bar:
    baz()

примерно сахара на:

try:
    bar = foo.__enter__()
    baz()
finally:
    if foo.__exit__(*sys.exc_info()) and sys.exc_info():
        raise

это часто полезно. Например

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

with myLock:
    frob_some_more()

контекстный менеджер может использоваться несколько раз.

в случае f это файл, он будет появляться за пределами with заявление.

например,

f = 42
print f
with open('6432134.py') as f:
    print f
print f

выведет:

42
<open file '6432134.py', mode 'r' at 0x10050fb70>
<closed file '6432134.py', mode 'r' at 0x10050fb70>

вы можете найти детали в PEP-0343 в разделе спецификация: оператор 'with'. правила области Python (что может быть раздражает) применить к f Как хорошо.

чтобы ответить на вопрос Хейкки в комментариях: Да, это поведение области видимости является частью спецификации языка python и будет работать на любых и всех совместимых питонах (включая PyPy, Jython и IronPython).