manager context python with-statement contextmanager

python - context - Significado de "con" declaración sin "como" palabra clave



context manager python (1)

El administrador de contexto puede opcionalmente devolver un objeto, para asignarlo al identificador nombrado por as . Y es el objeto devuelto por el método __enter__ que se asigna as , no necesariamente el administrador de contexto.

Usar as <identifier> ayuda cuando crea un nuevo objeto, como lo hace la llamada open() , pero no todos los administradores de contexto se crean solo para el contexto. Pueden ser reutilizables y ya han sido creados, por ejemplo.

Tome una conexión de base de datos . Usted crea la conexión de base de datos solo una vez, pero muchos adaptadores de base de datos le permiten usar la conexión como administrador de contexto; ingrese el contexto y se inicia una transacción, salga y la transacción se confirma (si se realiza correctamente) o se revierte (cuando hay una excepción):

with db_connection: # do something to the database

No es necesario crear nuevos objetos aquí, el contexto se ingresa con db_connection.__enter__() y se db_connection.__exit__() nuevamente con db_connection.__exit__() , pero ya tenemos una referencia al objeto de conexión.

Ahora, podría ser que el objeto de conexión produzca un objeto de cursor cuando se ingresa. Ahora tiene sentido asignar ese objeto de cursor en un nombre local:

with db_connection as cursor: # use cursor to make changes to the database

db_connection todavía no se llamó aquí, ya existía antes, y ya tenemos una referencia a él. Pero cualquier db_connection.__enter__() producido ahora se asigna al cursor y se puede usar de ahí en adelante.

Esto es lo que sucede con los objetos de archivo; open() devuelve un objeto de archivo, y el objeto de archivo fileobject.__enter__() devuelve el objeto de archivo en sí mismo , por lo que puede usar la llamada open() en una declaración with y asignar una referencia al objeto recién creado en un paso, en lugar de dos. Sin ese pequeño truco, tendrías que usar:

f = open(''myfile.txt'') with f: # use `f` in the block

Aplicando todo esto a tu ejemplo de sombreado; ya tienes una referencia a self.shader . Es bastante probable que self.shader.__enter__() devuelva una referencia a self.shader nuevamente, pero como ya tiene una referencia perfectamente útil, ¿por qué crear un nuevo local para eso?

Estoy familiarizado con el uso de python''s with statement como medio para asegurar la finalización de un objeto en el caso de que se produzca una excepción. Esto usualmente se ve como

with file.open(''myfile.txt'') as f: do stuff...

que es mano corta para

f = file.open(''myfile.txt''): try: do stuff... finally: f.close()

o cualquier otra rutina de finalización que pueda presentar una clase.

Recientemente encontré un código relacionado con OpenGL que presentaba esto:

with self.shader: (Many OpenGL commands)

Tenga en cuenta que la ausencia de cualquiera as palabra clave. ¿Esto indica que los métodos __enter__ y __exit__ de la clase aún deben llamarse, pero que el objeto nunca se usa explícitamente en el bloque (es decir, funciona a través de referencias globales o implícitas)? ¿O hay algún otro significado que me está eludiendo?