Para responder a su pregunta directamente:no veo ningún daño en cerrar al final de un with
bloquear. No puedo decir por qué no se hace en este caso. Pero, como hay una escasez de actividad en esta pregunta, hice una búsqueda en el historial del código y arrojaré algunas ideas (suposiciones ) sobre por qué close()
puede no ser llamado:
-
Existe una pequeña posibilidad de que las llamadas a
nextset()
puede arrojar una excepción; posiblemente esto se haya observado y se haya visto como indeseable. Esta puede ser la razón por la cual la versión más nueva decursors.py
contiene esta estructura enclose()
:def close(self): """Close the cursor. No further queries will be possible.""" if not self.connection: return self._flush() try: while self.nextset(): pass except: pass self.connection = None
-
Existe la posibilidad (algo remota) de que podría tomar algún tiempo revisar todos los resultados restantes sin hacer nada. Por lo tanto
close()
no se puede llamar para evitar hacer algunas iteraciones innecesarias. Si cree que vale la pena guardar esos ciclos de reloj es subjetivo, supongo, pero podría argumentar en la línea de "si no es necesario, no lo haga". -
Navegando por las confirmaciones de sourceforge, la funcionalidad fue agregada al tronco por esta confirmación en 2007 y parece que esta sección de
connections.py
no ha cambiado desde entonces. Esa es una fusión basada en esta confirmación , que tiene el mensajeY el código que cita nunca ha cambiado desde entonces.
Esto me lleva a mi pensamiento final:probablemente sea solo un primer intento / prototipo que funcionó y, por lo tanto, nunca se modificó.
Versión más moderna
Se vincula a la fuente de una versión heredada del conector. Observo que hay una bifurcación más activa de la misma biblioteca aquí , al que enlazo en mis comentarios sobre "versión más nueva" en el punto 1.
Tenga en cuenta que la versión más reciente de este módulo ha implementado __enter__()
y __exit__()
dentro del cursor
sí mismo:ver aquí
. __exit__()
aquí hace llamar a self.close()
y quizás esto proporcione una forma más estándar de usar la sintaxis with, por ejemplo,
with conn.cursor() as c:
#Do your thing with the cursor
Notas finales
N.B. Supongo que debería agregar, según tengo entendido, la recolección de basura (tampoco soy un experto) una vez que no hay referencias a conn
, se desasignará. En este punto, no habrá referencias al objeto del cursor y también se desasignará.
Sin embargo llamando a cursor.close()
no significa que será basura recolectada. Simplemente graba los resultados y establece la conexión en None
. Esto significa que no se puede reutilizar, pero no se recolectará como basura de inmediato. Puede convencerse de eso llamando manualmente a cursor.close()
después de tu with
bloquear y luego, digamos, imprimir algún atributo de cursor
N.B. 2 Creo que este es un uso algo inusual de with
sintaxis como conn
el objeto persiste porque ya está en el ámbito externo, a diferencia de, digamos, el with open('filename') as f:
donde no hay objetos dando vueltas con referencias después del final de with
bloquear.