Si es mejor abrir cursores con una instrucción with para asegurarse de que se elimine, así:
with arcpy.da.UpdateCursor(fc,fields) as cursor:
Luego, si se usa un cursor como iterable en una comprensión como esta:
d = {k:v for (k,v) in arcpy.da.SearchCursor(fc,fields)}
¿Es necesario eliminar el cursor después de usarlo en la comprensión?
da
cursores: sgillies.net/2011/02/01/get-with-it.html y help.arcgis.com/ es / arcgisdesktop / 10,0 / ayuda / index.html # // ... . En particular, mire los comentarios de @JasonScheirer al final del primer enlace.Respuestas:
Si es absolutamente necesario es una pregunta incorrecta. La pregunta es si es una buena idea.
Como regla general en la programación, debe evitar hacer cosas raras y usar la mejor herramienta para el trabajo . Si algo tiene una forma explícita de liberar recursos, simplemente explique la versión y termine con ella:
Lo que quizás no sepa es que la
with
cláusula en realidad invoca lógica adicional. Unawith
cláusula requiere un administrador de contexto, que debe tener un método__enter__
(invocado cuando se ingresa el bloque) y__exit__
(invocado cuando se sale del bloque). En particular, el__exit__
método se invoca independientemente de si se produjo una excepción, lo que garantiza que el programa siempre libera el recurso incluso en caso de error. Esto le proporciona a su código documentación explícita de cuándo se adquiere un recurso y cuándo se libera, y garantiza que se pueda liberar un recurso lo antes posible.Por el contrario, en realidad no puede depender del tiempo de ejecución para cerrarlo mágicamente de inmediato. Esto se debe a que la forma en que se cierra es invocando el destructor del objeto, lo que puede suceder o no de inmediato. Python no ofrece ninguna garantía acerca de cuándo se invoca un destructor, solo que eventualmente lo será cuando se recolecte basura del objeto. (Ver aquí .) Actualmente, Python está implementado para que ocurra tan pronto como ya no haya una referencia a un objeto. Pero es fácil propagar accidentalmente referencias a un objeto, y el tiempo de ejecución de Python puede cambiar.
Considere también el mantenimiento a largo plazo. No hay ninguna referencia a largo plazo ahora, pero lo que sucede en 6 meses cuando es necesario modificar el código de modo que no es una referencia? ¿Qué pasa si alguien más lo hace? Es posible que la persona que realiza el cambio no piense cambiar a un
with
bloque ya que no hay uno ya allí. Haga que la limpieza de sus recursos sea un hábito y tendrá muchos menos problemas.¿Realmente desea vincular su código a los detalles de implementación de la recolección de basura? ¿Desea tener que pensar constantemente si podría estar propagando accidentalmente una referencia a través de una excepción? No, tu no. Imagínese si eso sucedió cuando se invocó el script en ArcMap. El usuario se vería obligado a cerrar todo el proceso solo para liberar el archivo. Así que no te pongas en esa posición. Libere el recurso explícitamente. Guardar una línea de código no vale los riesgos de los problemas que puede causar. Los administradores de contexto son el mecanismo estándar para adquirir y liberar recursos en Python, y lo hacen muy bien.
La conclusión es que no liberarlo explícitamente es una mala idea.
Esto, por supuesto, supone que el código tiene alguna posibilidad de afectar a otra persona, como ponerlo en un script que alguien más necesitará ejecutar o mantener o podría retrasar la entrega de su trabajo si tiene que cerrar ArcMap por completo porque No puedo guardar tus cambios. Si eres el único que se verá afectado por un problema, entonces, por supuesto, vuela frente a las buenas prácticas todo lo que quieras.
fuente
No, no es necesario eliminar un
cursor
después de usarlo en una comprensión. Acursor
es una instancia de una clase, que es un objeto (todo en python es un objeto). Cada sesión de Python tiene unanamespace
que contiene referencias a todos los objetos de la sesión; piense en ello como un diccionario donde las claves son referencias a cada objeto, y los valores son los propios objetos. Cuando el 'recuento de referencia', el número de claves que se refieren a ese objeto, cae a cero, el objeto se elimina y la memoria se reasigna . Cuando usa acursor
en una comprensión, no hay referencia a ese objeto en el espacio de nombres. Una vez realizada la comprensión, el objeto se eliminará.No hay entrada en el espacio de nombres y, por lo tanto, no es necesario eliminar nada. ESRI también ilustra esta sintaxis en el ejemplo 2, aquí .
Para aclarar aún más, si ejecuta:
Verá que aparece un archivo .lock en el directorio (consulte su explorador de archivos). La referencia al cursor es
a
, lo que hará que elcursor
(y por lo tanto el bloqueo) persista hasta quea
se elimine. Entonces cuando corres:Se eliminará la entrada en el espacio de nombres y se liberará el bloqueo (el archivo .lock desaparecerá). Si tu corres:
No verá un archivo de bloqueo o desaparecerá cuando se complete el comando. Sin una entrada en el espacio de nombres, el
cursor
no es persistente.t
se refiere a la lista que acaba de crear, no a lacursor
utilizada para crearla.Para resumir, solo debe preocuparse por eliminar
cursors
cuando tienen una referencia en el espacio de nombres (es decir, cuando los ha asignado a una variable, comoa
en el ejemplo anterior).fuente
Bloquear con los cursores arcpy.da es casi lo mismo que bloquear con los cursores originales arcpy.
Después de probar su código, y como señaló gberard, no hay referencia al cursor una vez que finaliza la comprensión.
Además, no hay bloqueos en la clase de entidad después de que finaliza la comprensión.
fuente