Saltar al contenido

Explicando ‘__enter__’ y ‘__exit__’ de Python

Este post fue probado por nuestros especialistas así se garantiza la exactitud de este tutorial.

Solución:

Usando estos métodos mágicos (__enter__, __exit__) le permite implementar objetos que se pueden usar fácilmente con el with declaración.

La idea es que facilita la creación de código que necesita la ejecución de algún código de ‘limpieza’ (piense en ello como un try-finally cuadra). Alguna explicación más aquí.

Un ejemplo útil podría ser un objeto de conexión de base de datos (que luego cierra automáticamente la conexión una vez que la declaración ‘with’ correspondiente queda fuera del alcance):

class DatabaseConnection(object):

    def __enter__(self):
        # make a database connection and return it
        ...
        return self.dbconn

    def __exit__(self, exc_type, exc_val, exc_tb):
        # make sure the dbconnection gets closed
        self.dbconn.close()
        ...

Como se explicó anteriormente, use este objeto con el with declaración (es posible que deba hacer from __future__ import with_statement en la parte superior del archivo si está en Python 2.5).

with DatabaseConnection() as mydbconn:
    # do stuff

PEP343: la declaración ‘con’ también tiene una buena redacción.

si sabes que administradores de contexto Entonces no necesitas nada más para entender __enter__ y __exit__ métodos mágicos. Veamos un ejemplo muy sencillo.

En este ejemplo estoy abriendo miarchivo.txt con ayuda de abierto función. los intentar/finalmente block asegura que incluso si ocurre una excepción inesperada miarchivo.txt estara cerrado.

fp=open(r"C:UsersSharpElDesktopmyfile.txt")
try:
    for line in fp:
        print(line)
finally:
    fp.close()

Ahora estoy abriendo el mismo archivo con con declaración:

with open(r"C:UsersSharpElDesktopmyfile.txt") as fp:
    for line in fp:
        print(line) 

Si miras el código, no cerré el archivo y no hay intentar/finalmente cuadra. Porque con declaración se cierra automáticamente miarchivo.txt . Incluso puedes comprobarlo llamando print(fp.closed) attribute — que vuelve True.

Esto se debe a que los objetos de archivo (fp en mi ejemplo) devueltos por abierto La función tiene dos métodos incorporados. __enter__ y __exit__. También se le conoce como administrador de contexto. __enter__ se llama al método al principio de con bloquear y __exit__ El método se llama al final. Nota: con La declaración solo funciona con objetos que admiten el protocolo de administración de contexto, es decir, tienen __enter__ y __exit__ métodos. Una clase que implementa ambos métodos se conoce como clase de administrador de contexto.

Ahora vamos a definir nuestro propio administrador de contexto clase.

 class Log:
    def __init__(self,filename):
        self.filename=filename
        self.fp=None    
    def logging(self,text):
        self.fp.write(text+'n')
    def __enter__(self):
        print("__enter__")
        self.fp=open(self.filename,"a+")
        return self    
    def __exit__(self, exc_type, exc_val, exc_tb):
        print("__exit__")
        self.fp.close()

with Log(r"C:UsersSharpElDesktopmyfile.txt") as logfile:
    print("Main")
    logfile.logging("Test1")
    logfile.logging("Test2")

Espero que ahora tengas una comprensión básica de ambos. __enter__ y __exit__ métodos mágicos.

Me resultó extrañamente difícil localizar los documentos de Python para __enter__ y __exit__ métodos buscando en Google, así que para ayudar a otros aquí está el enlace:

https://docs.python.org/2/reference/datamodel.html#with-statement-context-managers
https://docs.python.org/3/reference/datamodel.html#with-statement-context-managers
(el detalle es el mismo para ambas versiones)

object.__enter__(self)

Ingrese el contexto de tiempo de ejecución relacionado con este objeto. los with vinculará el valor de retorno de este método a los objetivos especificados en la cláusula as de la declaración, si corresponde.

object.__exit__(self, exc_type, exc_value, traceback)

Salga del contexto de tiempo de ejecución relacionado con este objeto. Los parámetros describen la excepción que provocó la salida del contexto. Si se salió del contexto sin una excepción, los tres argumentos serán None.

Si se proporciona una excepción y el método desea suprimirla (es decir, evitar que se propague), debe devolver un true valor. De lo contrario, la excepción se procesará normalmente al salir de este método.

Tenga en cuenta que __exit__() los métodos no deben volver a generar la excepción pasada; esta es responsabilidad de la persona que llama.

Esperaba una descripción clara de la __exit__ argumentos del método. Esto falta pero podemos deducirlos…

Presumiblemente exc_type es la clase de la excepción.

Dice que no debe volver a generar la excepción pasada. Esto nos sugiere que uno de los argumentos podría ser una instancia de excepción real … ¿o tal vez se supone que debe crear una instancia usted mismo a partir del tipo y el valor?

Podemos responder mirando este artículo:
http://effbot.org/zone/python-with-statement.htm

Por ejemplo, el siguiente __exit__ El método se traga cualquier TypeError, pero deja pasar todas las demás excepciones:

def __exit__(self, type, value, traceback):
    return isinstance(value, TypeError)

… tan claramente value es una instancia de excepción.

y presumiblemente traceback es un objeto de rastreo de Python.

Sección de Reseñas y Valoraciones

Si aceptas, tienes la opción de dejar una división acerca de qué te ha gustado de este enunciado.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *