Apuntes_Python/02_conceptos/21_context_managers/README.md

3.2 KiB

Context Manager


Administradores de contexto

Son una gran herramienta para administrar recursos.
Permiten dedicar/localizar o liberar recursos cuando se requiera.

Ejemplo de context manager

with open('notas.txt', 'w') as file:
    archivo.write('algo que hacer...')

El administrador de contexto se encarga de cerrar correctamente
el archivo posterior a la ejecución de la sentencia with.
Incluso si se hubiese producido alguna excepción.

La forma 'manual', no adecuada, de hacerlo sería:

archvo = open('notas.txt', 'w')
try:
    file.write('algo que hacer...')
finally:
    file.close()

El uso del context manager es la forma adecuada de manejar archivos,
conexion a base de datos, multithreading/multipossesing Lock()

from threading import Lock

lock = Lock()

lock.acquire()
#....
lock.release()

Usando context manager

whit lock:
    #....

Implem. de context manager como clase personalizada

class ArchivoAdministrado:
    
    def __init__(self, nombre_archivo):
        print('init')
        self.nombre_archivo = nombre_archivo
    
    def __enter__(self):
        print('enter')
        self.archivo = open(self.nombre_archivo, 'w')
        return self.archivo

    def __exit__(self, excep_type, excep_value, excep_traceback):
        if self.archivo:
            self.archivo.close()
        if not excep_type:
            print('una excepcion ha sido manejada')
        #print('Excepcion: ',excep_type, excep_value, excep_traceback)  # Excepcion:  None None None
        print('exit')
        return True

with ArchivoAdministrado('notas.txt') as archivo:
    print('haz algunas cosas...')
    archivo.write('haz algunas cosas...')
    archivo.metodo_inexistente()
    # en caso de ocurrir alguna excepción, el context manager se encarga de el
    # y de cerrar el archivo correctamente.

print('ejecución continua normalmente')    

# init                                                                                                                                     
# enter                                                                                                                                    
# haz algunas cosas...                                                                                                                     
# exit
# ejecución continua normalmente

Implementacion de context manager como función

from contextlib import contextmanager

@contextmanager
def abrir_archivo_administrado(archivo):
    arch = open(archivo, 'w')
    try:
        yield arch
    finally:
        arch.close()

with abrir_archivo_administrado('notas.txt') as archivo:
    archivo.write('algo que hacer....')