Создать “с” блоком на нескольких менеджерах по контексту? [дубликат]

178
задан martineau 14 January 2019 в 14:30
поделиться

2 ответа

В Python 2.7 и 3.1 и выше вы можете написать:

with A() as X, B() as Y, C() as Z:
    do_something()

Обычно это лучший метод для использования, но если у вас есть список менеджеров контекста неизвестной длины, он вам понадобится из нижеприведенных методов.


В Python 3.3 вы можете ввести список менеджеров контекста неизвестной длины с помощью contextlib.ExitStack :

with ExitStack() as stack:
    for mgr in ctx_managers:
        stack.enter_context(mgr)
    # ...

Это позволяет вам создавать менеджеры контекста, как вы добавление их в ExitStack , что предотвращает возможную проблему с contextlib.nested (упоминается ниже).

contextlib2 предоставляет резервный порт ExitStack для Python 2.6 и 2.7.


В Python 2.6 и ниже вы можете использовать contextlib.nested :

from contextlib import nested

with nested(A(), B(), C()) as (X, Y, Z):
    do_something()

эквивалентно:

m1, m2, m3 = A(), B(), C()
with m1 as X:
    with m2 as Y:
        with m3 as Z:
            do_something()

Обратите внимание, что это не совсем то же самое, что обычно используется вложенные с , потому что A () , B () и C () будут вызываться изначально, перед входом в контекст менеджеры. Это не будет работать правильно, если одна из этих функций вызовет исключение.

contextlib.nested устарел в новых версиях Python в пользу вышеуказанных методов.

316
ответ дан 23 November 2019 в 20:15
поделиться

Первая часть вашего вопроса возможна в Python 3.1 .

С более чем одним элементом диспетчеры контекста обрабатываются так, как если бы несколько операторов with были вложены:

 с A () как a, B () как b:
сюита

эквивалентно

 с A () как a:
с B () как b:
сюита

Изменено в версии 3.1 : Поддержка множественных контекстных выражений

25
ответ дан 23 November 2019 в 20:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: