Quantcast
Viewing all articles
Browse latest Browse all 10

La sentencia ‘with’ de Python

‘with’ se introdujo en Python 2.5. En esa versión no estaba disponible directamente (eso fue a partir de la 2.6) y había que importarla con ‘with_statement’.

‘with’ es una sentencia relacionada con la gestión de recursos y su tratamiento cuando estos provocan una excepción o salen de su entorno.

Un ejemplo simple. Queremos abrir un fichero asignándolo a una variable, algo común en el quehacer diario.

try:
    f = open("test_with.txt", 'w')
    f.write("prueba")
except:
    print "error al abrir fichero"
finally:
    if f:
        f.close()

El código es bastante autoexplicativo. f es el nombre al que asignamos un objeto archivo. Esta operación, la apertura de un archivo y escritura en el, puede ocasionar varios errores de naturaleza múltiple (no esta el archivo, no tenemos permisos…). Por ello capturamos la excepción y gestionamos. Si todo sale bien pasaremos a la clausula ‘finally’ y allí gestionaremos la liberación del recurso, en este caso simplemente cerrar el archivo.

En este caso, somos nosotros los que estamos gestionando el recurso al cerrarlo ocurra o no una excepción. Mientras que somos responsables de responder ante las excepciones que este objeto nos quiera comunicar, gestionar el cierre del recurso es algo que el mismo recurso podría gestionar mejor que nosotros.

¿No estaría mejor abrir el archivo, operar sobre el y listo?

try:
    with open("test22.txt",'r') as f:
        f.write("prueba")
except:
    print "no esta el fichero"

En este fragmento ocurre eso precisamente. Gracias a ‘with’. Si observamos notaremos la ausencia del cierre del recurso, la comprobación de que sí está asignado a la variable ‘f’ y por supuesto, la clausula ‘finally’, ya que es el propio recurso quien se gestiona su propio cierre.

¿Como ocurre esto?

Cualquier tipo puede ser gestionado por ‘with’ a través de un “Manejador de contexto” (Context manager). Un manejador de contexto son dos funciones que van a ser llamadas por Python durante la ejecución. Los nombres son ‘__enter__’ y ‘__exit__’. Cuando se opera sobre el objeto se llama a ‘__enter__’ y cuando se sale, por cualquier motivo, se llama a ‘__exit__’.

Un ejemplo:

class With_Test(object):
    def __init__(self, n):
        print "en init..."
        self.n = n
    def __enter__(self):
        print "entrando..."
        return self
    def __exit__(self, exc_type, exec_value, traceback):
        print "saliendo..."
    def metodo(self):
        print "n vale: %s" % self.n

with With_Test(8) as wt:
    wt.metodo()

Esto imprimirá por pantalla:

bellucci:python david$ python test_with.py 
en init...
entrando...
n vale: 8
saliendo...

Si construimos nuestros objetos con este método abstraemos a los usuarios de nuestras clases de la gestión de cierre del recurso. La sintaxis es más clara y elegante.


Image may be NSFW.
Clik here to view.
Image may be NSFW.
Clik here to view.

Viewing all articles
Browse latest Browse all 10

Trending Articles