book - Administrador de contexto anidado de Python en varias líneas
django (4)
Esta pregunta ya tiene una respuesta aquí:
En Python 2.6, solíamos formatear nuestro administrador de contexto anidado de esa manera:
with nested(
context1,
context2
) as a, b:
pass
Desde Python 2.7 y en adelante, nested
está en desuso. He visto muchos ejemplos de administrador de contexto múltiple en una sola línea, pero no puedo encontrar una sintaxis que los permita en varias líneas. ¿Cómo harías esto?
# That''s working fine
with context1 as a, context2 as b:
pass
# But how do we make it multine?
# These are not working
with (
context1,
context2
) as a, b:
pass
with context1 as a,
context2 as b:
pass
Caracteres de barra invertida
Dos o más líneas físicas se pueden unir en líneas lógicas usando caracteres de barra invertida (
/
)
(citando la sección de unión de línea explícita )
Si desea colocar los administradores de contexto en líneas diferentes, puede hacer que eso funcione al terminar las líneas con barras invertidas:
with context1 as a,/
context2 as b:
pass
contextlib.ExitStack
contextlib.ExitStack
es una
administrador de contexto que está diseñado para facilitar la combinación programática de otros administradores de contexto y funciones de limpieza, especialmente aquellos que son opcionales o controlados por datos de entrada.
Está disponible en Python 3.3 y más reciente, y permite ingresar fácilmente un número variable de administradores de contexto. Para solo dos gestores de contexto el uso es así:
from contextlib import ExitStack
with ExitStack() as es:
a = es.enter_context(context1)
b = es.enter_context(context2)
Anidamiento
Es posible dividir una expresión de contexto en varias declaraciones anidadas :
Con más de un elemento, los administradores de contexto se procesan como si se anidaran múltiples con declaraciones:
with A() as a, B() as b:
suite es equivalente a
with A() as a: with B() as b: suite
(desde el con la declaración )
Hay una manera de usar creativamente los paréntesis y evitar la barra invertida: paréntesis de la expresión anterior as
. Aunque no muy a la vista:
with (
open(''/etc/passwd'')) as foo, (
open(''/tmp/bar'')) as bar:
pass # this parses correctly
Es fácil anidar más y más si es necesario.
Su ejemplo es equivalente a:
with context1 as a:
with context2 as b:
pass
que se ve bien en dos líneas.
Referencia: https://docs.python.org/2.7/reference/compound_stmts.html#the-with-statement
with context1 as a, /
context2 as b:
pass
Como cualquier salto de línea, la barra invertida proporciona la solución