GeeksforGeeks
Gestión de recursos: En cualquier lenguaje de programación, el uso de recursos como operaciones de archivos o conexiones a bases de datos es muy común. Pero la oferta de estos recursos es limitada. Por lo tanto, el principal problema radica en asegurarse de liberar estos recursos después de su uso. Si no se liberan, provocará una fuga de recursos y puede hacer que el sistema se ralentice o se bloquee. Sería muy útil si el usuario tuviera un mecanismo para la configuración automática y la eliminación de recursos.En Python, se puede lograr mediante el uso de gestores de contexto que facilitan el manejo adecuado de los recursos. La forma más común de realizar operaciones de archivos es mediante el uso de la palabra clave with, como se muestra a continuación:
with
open
(
"test.txt"
) as f:
data
=
f.read()
Let’s take the example of file gestión. Cuando se abre un archivo, se consume un descriptor de archivo que es un recurso limitado. Un proceso solo puede abrir un cierto número de archivos a la vez. El siguiente programa lo demuestra.
file_descriptors
=
for
x
in
range
(
100000
):
file_descriptors.append(
open
(
'test.txt'
,
'w'
))
Salida:
Traceback (most recent call last): File "context.py", line 3, in OSError: Too many open files: 'test.txt'
Un mensaje de error diciendo que hay demasiados archivos abiertos. El ejemplo anterior es un caso de fuga de descriptores de archivo. Sucede porque hay demasiados archivos abiertos y no están cerrados. Puede haber posibilidades de que un programador se olvide de cerrar un archivo abierto.
Administrar recursos usando el administrador de contexto :
Supongamos que un bloque de código genera una excepción o si tiene un algoritmo complejo con múltiples rutas de retorno, se vuelve engorroso cerrar un archivo en todos los lugares.
Generalmente en otros idiomas cuando se trabaja con archivos, try-except-finally se usa para asegurarse de que el recurso de archivo se cierra después del uso, incluso si hay una excepción.Python proporciona una forma fácil de administrar recursos: Administradores de contexto. Se utiliza la palabra clave with. Cuando se evalúa, debe dar lugar a un objeto que realice la administración de contexto. Los gestores de contexto se pueden escribir usando clases o funciones(con decoradores).
Crear un administrador de contexto:
Al crear administradores de contexto utilizando clases, el usuario debe asegurarse de que la clase tenga los métodos: __enter__() y __exit__(). El__ enter __() devuelve el recurso que necesita ser administrado y el__ exit _ _ () no devuelve nada, pero realiza las operaciones de limpieza.En primer lugar, vamos a crear una clase simple llamada ContextManager para comprender la estructura básica de la creación de gestores de contexto utilizando clases, como se muestra a continuación:
class
ContextManager():
def
__init__(
self
):
print
(
'init method called'
)
def
__enter__(
self
):
print
(
'enter method called'
)
return
self
def
__exit__(
self
, exc_type, exc_value, exc_traceback):
print
(
'exit method called'
)
with ContextManager() as manager:
print
(
'with statement block'
)
Output:
init method calledenter method calledwith statement blockexit method called
En este caso se crea un objeto ContextManager. Esto se asigna a la variable después de la palabra clave as, es decir, administrador. Al ejecutar el programa anterior, se ejecuta lo siguiente en secuencia:
- __init__()
- __enter__()
- cuerpo de la instrucción (código dentro del bloque with)
- __exit__()
Administración de archivos mediante el administrador de contexto :
para crear una clase que ayude en la administración de recursos de archivos.La clase FileManager ayuda a abrir un archivo, escribir / leer contenido y luego cerrarlo.
class
FileManager():
def
__init__(
self
, filename, mode):
self
.filename
=
filename
self
.mode
=
mode
self
.
file
=
None
def
__enter__(
self
):
self
.
file
=
open
(
self
.filename,
self
.mode)
return
self
.
file
def
__exit__(
self
, exc_type, exc_value, exc_traceback):
self
.
file
.close()
with FileManager(
'test.txt'
,
'w'
) as f:
f.write(
'Test'
)
print
(f.closed)
Salida:
True
Administración de archivos mediante el administrador de contexto y la instrucción with:
Al ejecutar el bloque with, se realizan las siguientes operaciones en secuencia:
- Se crea un objeto Gestor de archivos con test.txt como nombre de archivo y w (write) como modo cuando se ejecuta el método __init__.
- El método _ _ enter _ _ abre la prueba.archivo txt en modo de escritura (operación de configuración) y devuelve el objeto Gestor de archivos a la variable f.
- El texto ‘Test’ se escribe en el archivo.
- El método __exit__ se encarga de cerrar el archivo al salir del bloque with(operación de desmontaje).
Cuando se ejecuta print(f.closed), la salida es Verdadera, ya que el administrador de archivos ya se ha encargado de cerrar el archivo, lo que de otro modo debía hacerse explícitamente.
Administración de conexiones de base de datos usando el administrador de contexto:
Vamos a crear un sistema simple de administración de conexiones de base de datos. El número de conexiones de base de datos que se pueden abrir a la vez también es limitado(al igual que los descriptores de archivo). Por lo tanto, los administradores de contexto son útiles para administrar las conexiones a la base de datos, ya que podría haber posibilidades de que el programador se olvide de cerrar la conexión.
from
pymongo
import
MongoClient
class
MongoDBConnectionManager():
def
__init__(
self
, hostname, port):
self
.hostname
=
hostname
self
.port
=
port
self
.connection
=
None
def
__enter__(
self
):
self
.connection
=
MongoClient(
self
.hostname,
self
.port)
return
self
def
__exit__(
self
, exc_type, exc_value, exc_traceback):
self
.connection.close()
with MongoDBConnectionManager(
'localhost'
,
'27017'
) as mongo:
collection
=
mongo.connection.SampleDb.test
data
=
collection.find({
'_id'
:
1
})
print
(data.get(
'name'
))
conexión de Base de datos de gestión de uso de contexto manager y con la instrucción :
En la ejecución de la con el bloque, las siguientes operaciones ocurren en secuencia:
- Un MongoDBConnectionManager objeto se crea con localhost como hostnamename y 27017 como el puerto cuando __init__ se ejecuta el método.
- El método _ _ enter _ _ abre la conexión mongodb y devuelve el objeto MongoDBConnectionManager a la variable mongo.
- Se accede a la colección de pruebas de la base de datos SampleDb y se recupera el documento con _id = 1. Se imprime el campo nombre del documento.
- El método __exit__ se encarga de cerrar la conexión al salir del bloque with(operación de desmontaje).