106 lines
3.2 KiB
Markdown
106 lines
3.2 KiB
Markdown
|
# Context Manager
|
||
|
|
||
|
- [Ejemplo](https://gitea.kickto.net/devfzn/Apuntes_Python/src/branch/master/02_conceptos/21_context_managers#ejemplo-de-context-manager)
|
||
|
- [Implementación como clase personalizada](https://gitea.kickto.net/devfzn/Apuntes_Python/src/branch/master/02_conceptos/21_context_managers#implem-de-context-manager-como-clase-personalizada)
|
||
|
- [Implementación como función](https://gitea.kickto.net/devfzn/Apuntes_Python/src/branch/master/02_conceptos/21_context_managers#implementacion-de-context-manager-como-funci%C3%B3n)
|
||
|
|
||
|
----
|
||
|
|
||
|
## Administradores de contexto
|
||
|
|
||
|
Son una gran herramienta para administrar recursos.
|
||
|
Permiten dedicar/localizar o liberar recursos cuando se requiera.
|
||
|
|
||
|
#### Ejemplo de context manager
|
||
|
```python
|
||
|
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:
|
||
|
```python
|
||
|
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()
|
||
|
|
||
|
```python
|
||
|
from threading import Lock
|
||
|
|
||
|
lock = Lock()
|
||
|
|
||
|
lock.acquire()
|
||
|
#....
|
||
|
lock.release()
|
||
|
```
|
||
|
|
||
|
Usando context manager
|
||
|
```python
|
||
|
whit lock:
|
||
|
#....
|
||
|
```
|
||
|
|
||
|
## Implem. de context manager como clase personalizada
|
||
|
|
||
|
```python
|
||
|
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
|
||
|
```python
|
||
|
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....')
|
||
|
```
|