con una declaración en Python

| | | | | | | | | | | | | | | | | | | | | | | | | |

# manejo de archivos


# 1) no se usa con instrucción

archivo = open ( `file_path` , `w` )

archivo . write ( `¡hola mundo!` )

archivo . close ()


# 2) no se usa con declaración

archivo = abrir ( `ruta_archivo` , ` w` )

prueba :

archivo . escribir ( `hola mundo` )

finalmente :

archivo .close()


# uso con instrucción

con abierto ( ` file_path` , `w` ) as < código clase = "funciones"> archivo :

archivo . escribir ( `¡hola mundo!` )

Tenga en cuenta que, a diferencia de las dos primeras implementaciones, no es necesario llamar a file.close () cuando se usa la instrucción with . La declaración with en sí misma garantiza que los recursos se adquieran y liberen correctamente. Una excepción durante file.write () en la primera implementación puede evitar que el archivo se cierre correctamente, lo que puede provocar varios errores en el código, es decir, muchos cambios en los archivos no surten efecto hasta que el archivo es correctamente cerrado.

El segundo enfoque en el ejemplo anterior se ocupa de todas las excepciones, pero el uso de la declaración with hace que el código sea compacto y mucho más legible. Por lo tanto, la declaración with ayuda a evitar errores y fugas al garantizar que el recurso se libere correctamente cuando el código que usa el recurso se ejecute por completo. La declaración with se usa comúnmente con secuencias de archivos como se muestra arriba, así como con bloqueos, sockets, subprocesos, telnets, etc.

Compatibilidad con la declaración "with" en objetos personalizados

No hay nada especial en open() que lo hace utilizable con la declaración with with y la misma funcionalidad puede proporcionarse en objetos personalizados. La compatibilidad con las aserciones with en sus objetos garantiza que nunca deje recursos abiertos.
Para usar el operador with en objetos personalizados, solo necesita agregar el __enter __ () y __exit __ () métodos a los métodos del objeto. Considere el siguiente ejemplo para aclarar más.


# escritor de archivos simple


class MessageWriter ( object ):

def __ init __ ( self , nombre_archivo):

self . nombre_archivo = nombre_archivo


def __ ingrese __ ( self ):

self . archivo = abrir ( self . file_name, ` w` < clase de código = "simple">)

return self . archivo

def __ exit __ ( self ):

self . archivo . cerrar ()


# usar con operador con MessageWriter


con MessageWriter ( `my_file.txt` ) como xfile:

xfile.write ( `hola mundo` )

Echemos un vistazo al código anterior. Si observa que la palabra clave with sigue al constructor MessageWriter . Una vez que la ejecución ingresa al contexto with afirmando que se crea un objeto MessageWriter y python llama al método __enter __ () . En este __enter __(), inicialice el recurso que desea usar en el objeto. Este __enter __ () siempre debe devolver un identificador del recurso recibido.

¿Qué son los descriptores de recursos?
Son descriptores proporcionados por el sistema operativo para acceder a los recursos solicitados. En el siguiente bloque de código, file es el descriptor de recursos del flujo de archivos.


file < clase de código = "palabra clave"> = abrir ( `hola.txt ` )

En el ejemplo proporcionado de MessageWriter __enter __ () el método __enter __ () crea un descriptor de archivo y lo devuelve. El nombre xfile se usa aquí para referirse al descriptor de archivo devuelto por el método __enter __ () . El bloque de código que usa el recurso resultante se coloca dentro del bloque de declaración with. Una vez que se ejecuta el código dentro del bloque with , el método __exit __ () es __exit __ () . Todos los recursos recibidos se liberan en __exit __(). Así es como usamos la aserción with con objetos definidos por el usuario.

Esta interfaz de método es __enter __ () y __exit __ () que brinda soporte para la declaración with en objetos personalizados se llama Context Manager .

El módulo contextlib

El administrador de contexto basado en clases, como se muestra arriba, no es la única forma de admitir la instrucción with en objetos personalizados. El módulo contextlib proporciona algunas abstracciones más integradas en la interfaz base administrador de contexto Así es como podemos reescribir el administrador de contexto para el objeto MessageWriter usando el módulo contextlib .


de contextlib importar administrador de contexto


class MessageWriter ( objeto ):

def __ init __ ( self , nombre de archivo):

self . nombre_archivo = nombre de archivo

@ contextmanager

def archivo_abierto ( self ):

< /código> probar :

archivo < clase de código = "palabra clave"> = abrir ( self .nombre_archivo, `w` )

rendimiento archivo

finalmente :

archivo . cerrar ()


# usar

escritor_mensaje = MessageWriter ( `hola.txt` )

with message_writer.open_file() as my_file:

mi_archivo.escribir ( `hola mundo` )

< / p>

En este ejemplo de código, debido a la declaración generador de funciones .
Cuando open_file () este open_file () , crea un identificador para un recurso llamado file . Este descriptor de recursos luego se pasa a la persona que llama y se representa aquí mediante la variable my_file. Después de ejecutar el código dentro del bloque with , el control del programa vuelve a la función open_file () . La función open_file() reanuda su ejecución y ejecuta el código siguiendo la declaración yield. Esta parte del código que aparece después de la sentencia yield libera los recursos resultantes. @contextmanager aquí está