Многострочный Python с инструкцией
Что такое чистый способ создания многострочного with
в python? Я хочу открыть несколько файлов внутри одного with
, но он достаточно далеко вправо, что я хочу его на нескольких строках. Вот так:
class Dummy:
def __enter__(self): pass
def __exit__(self, type, value, traceback): pass
with Dummy() as a, Dummy() as b,
Dummy() as c:
pass
К сожалению, это SyntaxError
. Поэтому я попробовал это:
with (Dummy() as a, Dummy() as b,
Dummy() as c):
pass
Также синтаксическая ошибка. Однако это сработало:
with Dummy() as a, Dummy() as b,\
Dummy() as c:
pass
Но что, если я хочу разместить комментарий? Это не работает:
with Dummy() as a, Dummy() as b,\
# my comment explaining why I wanted Dummy() as c\
Dummy() as c:
pass
Также нет очевидных изменений в размещении \
s.
Есть ли простой способ создать многострочный оператор with
, который позволяет делать комментарии внутри него?
Ответы
Ответ 1
Учитывая, что вы пометили этот Python 3, если вам нужно добавить комментарии к вашим контекстным менеджерам, я бы использовал contextlib.ExitStack
:
with ExitStack() as stack:
a = stack.enter_context(Dummy()) # Relevant comment
b = stack.enter_context(Dummy()) # Comment about b
c = stack.enter_context(Dummy()) # Further information
Это эквивалентно
with Dummy() as a, Dummy() as b, Dummy() as c:
Это дает то преимущество, что вы можете генерировать свои контекстные менеджеры в цикле, вместо того, чтобы указывать их по отдельности. В документации приведен пример того, что если вы хотите открыть несколько файлов и у вас есть имена файлов в списке, вы можете сделать
with ExitStack() as stack:
files = [stack.enter_context(open(fname)) for fname in filenames]
Если ваши контекстные менеджеры занимают так много места на экране, что вы хотите поместить комментарии между ними, вам, вероятно, хватит, чтобы использовать какой-то цикл.
Как г-н Бессмертный упоминает в комментариях, есть контекстный заголовок контекста на PyPI под именем contextlib2
. Если вы на Python 2, вы можете использовать реализацию backport ExitStack
.
Ответ 2
Это кажется мне самым утонченным:
with open('firstfile', 'r') as (f1 # first
), open('secondfile', 'r') as (f2 # second
):
pass
Ответ 3
Это не совсем чисто, но вы можете сделать это:
with Dummy() as a, Dummy() as b, (
#my comment
Dummy()) as c:
pass
Нет синтаксических ошибок, но это не самый чистый. Вы также можете сделать это:
with Dummy() as a, Dummy() as b, Dummy(
#my comment
) as c:
pass
Подумайте о том, как найти способ сделать это, не используя комментарии в середине with
.
Ответ 4
Я бы сделал все просто и читабельно, добавив комментарий перед оператором with
или в самой строке:
# my comment explaining why I wanted Dummy() as c
with Dummy() as a, Dummy() as b,\
Dummy() as c: # or add the comment here
pass
Ответ 5
Как и ответ TigerhawkT3, но с отступом, который не вызывает ошибку pycodestyle E124:
with (
open('firstfile', 'r')) as f1, ( # first
open('secondfile', 'r')) as f2: # second
pass
ИМО все еще безобразно, но, по крайней мере, проходит мимо.