Рассмотрим следующий пример:
with open('a.txt') as f:
pass
# Is f supposed to be defined here?
Я прочитал языковую документацию (2.7) для оператора with, а также PEP-343, но, насколько я могу судить, они ничего не говорят по этому поводу.
В CPython 2.6.5 f
кажется, что он определен вне блока with, но я бы предпочел не полагаться на детали реализации, которые могут измениться.
Ответы:
Да, диспетчер контекста будет доступен вне оператора with, и он не зависит от реализации или версии. Операторы with не создают новую область выполнения.
источник
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 в разделе « Спецификация: Заявление с» . К ним также применяются правила области видимости Python (которые могут раздражать )
f
.источник
[x for x in [1]]
.x
доступен за пределами этого. Сделать это в генератор:(x for x in [1])
. Сейчасx
нет в наличии. Я, кажется, припоминаю, что это было изменено в Python 3, так что даже при понимании спискаx
не будет утечки, но сейчас я не могу найти ссылку.Чтобы ответить на вопрос Хейкки в комментариях: да, это поведение области видимости является частью спецификации языка python и будет работать на всех без исключения совместимых Python (включая PyPy, Jython и IronPython).
источник