Можно ли объявить более одной переменной с помощью with
оператора в Python?
Что-то вроде:
from __future__ import with_statement
with open("out.txt","wt"), open("in.txt") as file_out, file_in:
for line in file_in:
file_out.write(line)
... или проблема очистки двух ресурсов одновременно?
python
with-statement
рыба фугу
источник
источник
Ответы:
Это возможно в Python 3 начиная с версии 3.1 и Python 2.7 . Новый
with
синтаксис поддерживает несколько контекстных менеджеров:В отличие от
contextlib.nested
, это гарантирует , чтоa
иb
будет иметь их__exit__()
называеться , даже еслиC()
и это__enter__()
метод вызывает исключение.Вы также можете использовать более ранние переменные в более поздних определениях (ч / т Ахмад ниже):
источник
with open('./file') as arg.x = file:
?as
это необязательно.as
требуется, если вам нужен объектa
илиb
, но целикомas a
илиas b
не требуетсяcontextlib.nested
поддерживает это:Обновление:
Цитировать документацию, касающуюся
contextlib.nested
:См . Ответ Рафала Доугирда для получения дополнительной информации.
источник
nested
менеджер контекста является ошибкой и никогда не должен использоваться. В этом примере, если при открытии второго файла возникает исключение, первый файл вообще не будет закрыт, что полностью разрушит цель использования контекстных менеджеров.with
блоков. Менеджеры создаются по порядку перед входом с блоками: m1, m2, m3 = A (), B (), C (). Если B () или C () завершаются неудачно с исключением, тогда ваша единственная надежда на правильное завершение A ( ) является сборщиком мусора.Обратите внимание, что если вы разбиваете переменные на строки, вы должны использовать обратную косую черту для переноса строк.
Круглые скобки не работают, так как Python вместо этого создает кортеж.
Поскольку у кортежей отсутствует
__enter__
атрибут, вы получаете ошибку (не описательную и не идентифицирующую тип класса):Если вы попытаетесь использовать
as
в скобках, Python ловит ошибку во время разбора:https://bugs.python.org/issue12782, похоже, связано с этой проблемой.
источник
Я думаю, что вы хотите сделать это вместо:
источник
Начиная с Python 3.3, вы можете использовать класс
ExitStack
изcontextlib
модуля.Он может управлять динамическим числом контекстно-зависимых объектов, что означает, что он окажется особенно полезным, если вы не знаете, сколько файлов вы собираетесь обрабатывать.
Канонический вариант использования, упомянутый в документации, управляет динамическим числом файлов.
Вот общий пример:
Вывод:
источник
В Python 3.1+ вы можете указать несколько выражений контекста, и они будут обрабатываться так, как если бы несколько
with
выражений были вложенными:эквивалентно
Это также означает, что вы можете использовать псевдоним из первого выражения во втором (полезно при работе с соединениями / курсорами БД):
источник