¿Cuál es el Python “with” se utiliza?
Pregunta
Estoy tratando de entender la sentencia with en Python. Donde quiera que miro se habla de abrir y cerrar un archivo, y está destinado a reemplazar el bloque try-fin. Podría alguien publicar algunos otros ejemplos también. Sólo estoy tratando de salir frasco y hay declaraciones con abundancia en ella. Sin duda pide a alguien para proporcionar un poco de claridad en él.
Solución
Hay una muy buena explicación aquí . Básicamente, la sentencia with llama a dos métodos especiales sobre el objeto asociado. Los __enter__ y __exit__ métodos. El método devuelve introducir la variable asociada con la expresión "with". Mientras que el método __exit__ se llama después de que los ejecuta statement para manejar cualquier limpieza (como el cierre de un apuntador de archivo).
Otros consejos
La idea de la declaración with
es hacer que "hacer lo correcto" el camino de menor resistencia. Mientras que el ejemplo de archivo es el más simple, enhebrar cerraduras en realidad dar un ejemplo más clásico de código no, obviamente, con errores:
try:
lock.acquire()
# do stuff
finally:
lock.release()
Este código se rompe - si la adquisición de bloqueo nunca falla, o bien se produce la excepción mal (ya que el código intentará liberar un bloqueo que nunca adquirida), o, peor aún, si se trata de una cerradura recursiva, se se dará a conocer antes de tiempo. Las miradas correctas código como el siguiente:
lock.acquire()
try:
# do stuff
finally:
# If lock.acquire() fails, this *doesn't* run
lock.release()
Mediante el uso de una declaración with
, se hace imposible conseguir este mal, ya que está integrado en el gestor de contexto:
with lock: # The lock *knows* how to correctly handle acquisition and release
# do stuff
El otro lugar donde la declaración with
ayuda en gran medida es similar a la ventaja importante de la función y de clase decoradores: toma código "de dos piezas", que pueden estar separados por un número arbitrario de líneas de código (la definición de función para decoradores , el bloque try
en el caso actual) y lo convierte en código de "una sola pieza", donde el programador declara simplemente por adelantado lo que están tratando de hacer.
Para ejemplos cortos, esto no se ve como una gran ganancia, pero en realidad hace una gran diferencia en la revisión de código. Cuando veo lock.acquire()
en una pieza de código, lo que necesito para desplazarse hacia abajo y compruebe si hay lock.release()
correspondiente. Cuando veo with lock:
, sin embargo, no se necesita tal cheque -. Puedo ver inmediatamente que el bloqueo se libera correctamente
Hay doce ejemplos del uso de with
en PEP343 , incluido el archivo ejemplo -open:
- Una plantilla para asegurar que una cerradura, adquirida en el inicio de una bloque, se libera cuando el bloque se deja
- Una plantilla para abrir un archivo que garantiza que el archivo es cerrado cuando el bloque se deja
- Una plantilla para confirmar o deshacer una base de datos transacción
- Ejemplo 1 reescrito sin un generador
- Redirigir stdout temporalmente
- Una variante de abierto () que también devuelve una condición de error
- Otro ejemplo útil sería una operación que bloquea señales
- Otro uso de esta función es el contexto decimal
- Este es un gestor de contexto simple para el módulo decimal
- Un gestor de contexto "de cierre objeto" genérico
- un contexto liberado () para liberar temporalmente un bloqueo previamente adquiridos mediante el canje de la adquisición () y liberación () llama
- A "anidado" gestor de contexto que anida automáticamente el contextos suministrada desde izquierda a derecha para evitar la excesiva indentación