Vi esto en el código de alguien. Qué significa eso?
def __enter__(self):
return self
def __exit__(self, type, value, tb):
self.stream.close()
from __future__ import with_statement#for python2.5
class a(object):
def __enter__(self):
print 'sss'
return 'sss111'
def __exit__(self ,type, value, traceback):
print 'ok'
return False
with a() as s:
print s
print s
python
oop
with-statement
zjm1126
fuente
fuente
Respuestas:
El uso de estos métodos mágicos (
__enter__
,__exit__
) le permite implementar objetos que se pueden usar fácilmente con lawith
instrucción.La idea es que facilita la creación de código que necesita algún código 'cleandown' ejecutado (piense en él como un
try-finally
bloque). 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 de alcance):
Como se explicó anteriormente, use este objeto con la
with
declaración (es posible que deba hacerlofrom __future__ import with_statement
en la parte superior del archivo si está en Python 2.5).PEP343 - La declaración ' con ' también tiene una buena redacción.
fuente
__enter__
debería volverself
siempre, ya que solo se pueden invocar otros métodos de la clase en el contexto.def __enter__(self)
en PEP 343 y nadie lo hacereturn self
: python.org/dev/peps/pep-0343 . ¿Por qué piensas eso?self
objeto como se explica aquí: stackoverflow.com/questions/38281853/… 2) self.XYZ es solo parte del objeto propio y devolver el asa solo a eso me parece inapropiado desde el punto de vista del mantenimiento. Preferiría devolver el identificador para completar el objeto y luego proporcionar API públicas solo a losself
objetos de componentes , que quiero exponer al usuario como enwith open(abc.txt, 'r') as fin: content = fin.read()
self
a partir__enter__
, que es ¿cómo es que puede procesar el archivo comof
en el interiorwith open(...) as f
Si sabes qué son los gestores de contexto, entonces no necesitas nada más que entender
__enter__
y__exit__
métodos mágicos. Veamos un ejemplo muy simple.En este ejemplo, estoy abriendo myfile.txt con la ayuda de la función de apertura . El bloque try / finally asegura que incluso si se produce una excepción inesperada, myfile.txt se cerrará.
Ahora estoy abriendo el mismo archivo con la declaración:
Si observa el código, no cerré el archivo y no hay ningún intento / finalmente bloqueo. Porque con la declaración se cierra automáticamente myfile.txt . Incluso puede verificarlo llamando al
print(fp.closed)
atributo, que regresaTrue
.Esto se debe a que los objetos de archivo (fp en mi ejemplo) devueltos por la función abierta tienen dos métodos integrados
__enter__
y__exit__
. También se conoce como gestor de contexto.__enter__
El método se llama al comienzo de with block y el__exit__
método se llama al final. Nota: con la declaración sólo funciona con objetos que soportan el protocolo contexto mamangement es decir, tienen__enter__
y__exit__
métodos. Una clase que implementa ambos métodos se conoce como clase de administrador de contexto.Ahora definamos nuestra propia clase de gestor de contexto .
Espero que ahora tengas una comprensión básica de ambos
__enter__
y de__exit__
los métodos mágicos.fuente
Google me pareció extrañamente difícil localizar los documentos
__enter__
y__exit__
métodos de Python, 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)
Esperaba una descripción clara de los
__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 plantear la excepción aprobada. Esto nos sugiere que uno de los argumentos podría ser una instancia de excepción real ... ¿o tal vez se supone que debes instanciarlo tú mismo a partir del tipo y el valor?
Podemos responder mirando este artículo:
http://effbot.org/zone/python-with-statement.htm
... tan claramente
value
es una instancia de excepción.Y presumiblemente
traceback
es un objeto de rastreo de Python .fuente
Además de las respuestas anteriores para ejemplificar el orden de invocación, un ejemplo de ejecución simple
Produce la salida:
Un recordatorio: cuando se usa la sintaxis
with myclass() as mc
, la variable mc obtiene el valor devuelto por__enter__()
, en el caso anteriorNone
. Para tal uso, necesita definir el valor de retorno, como:fuente
Intente agregar mis respuestas (mi pensamiento de aprender):
__enter__
y[__exit__]
ambos son métodos que se invocan al entrar y salir del cuerpo de " la declaración con " ( PEP 343 ) y la implementación de ambos se llama administrador de contexto.la declaración with tiene la intención de ocultar el control de flujo de la cláusula try finalmente y hacer que el código sea inescrutable.
La sintaxis de la instrucción with es:
que se traducen a (como se menciona en PEP 343):
prueba un código:
e intente ahora manualmente (siguiendo la sintaxis de traducción):
el resultado del lado del servidor igual que antes
lo siento por mi mal inglés y mis explicaciones poco claras, gracias ...
fuente
Esto se llama administrador de contexto y solo quiero agregar que existen enfoques similares para otros lenguajes de programación. Compararlos podría ser útil para comprender el administrador de contexto en python. Básicamente, se utiliza un administrador de contexto cuando se trata de algunos recursos (archivo, red, base de datos) que deben inicializarse y, en algún momento, eliminarse (desecharse). En Java 7 y superior tenemos una gestión automática de recursos que toma la forma de:
Tenga en cuenta que Session necesita implementar
AutoClosable
o una de sus (muchas) subinterfaces.En C # , hemos utilizado declaraciones para administrar recursos que toman la forma de:
En el que
Session
debe implementarIDisposable
.En python , la clase que usamos debería implementar
__enter__
y__exit__
. Entonces toma la forma de:Y como otros señalaron, siempre puede usar la declaración try / finally en todos los idiomas para implementar el mismo mecanismo. Esto es solo azúcar sintáctico.
fuente