S'il est préférable d'ouvrir les curseurs à l'aide d'une instruction with pour vous assurer qu'il est supprimé, comme ceci:
with arcpy.da.UpdateCursor(fc,fields) as cursor:
Ensuite, si un curseur est utilisé comme itérable dans une compréhension comme celle-ci:
d = {k:v for (k,v) in arcpy.da.SearchCursor(fc,fields)}
Faut-il supprimer le curseur après l'avoir utilisé dans la compréhension?
da
curseurs: sgillies.net/2011/02/01/get-with-it.html et help.arcgis.com/ fr / arcgisdesktop / 10.0 / help / index.html # //… . En particulier, regardez les commentaires de @JasonScheirer au bas du premier lien.Réponses:
Que ce soit absolument nécessaire n'est pas la bonne question à poser. La question est de savoir si c'est une bonne idée.
En règle générale dans la programmation, vous devez éviter de faire des choses étranges et utiliser le meilleur outil pour le travail . Si quelque chose a un moyen explicite de libérer des ressources, il suffit de rendre la version explicite et d'en finir avec:
Ce que vous ignorez peut-être, c'est que la
with
clause invoque en fait une logique supplémentaire. Unewith
clause nécessite un gestionnaire de contexte, qui doit avoir une méthode__enter__
(invoquée lorsque le bloc est entré) et__exit__
(invoquée lorsque le bloc est quitté). En particulier, la__exit__
méthode est invoquée indépendamment du fait qu'une exception s'est produite, garantissant que le programme libère toujours la ressource même en cas d'erreur. Cela donne à votre code une documentation explicite sur le moment où une ressource est acquise et quand elle est libérée, et cela garantit qu'une ressource peut être libérée dès que possible.En revanche, vous ne pouvez pas réellement dépendre du runtime pour le fermer comme par magie immédiatement pour vous. Cela est dû au fait qu'il se ferme en invoquant le destructeur de l'objet, ce qui peut ou non se produire immédiatement. Python ne fait aucune garantie quant à l'invocation d'un destructeur, mais seulement que ce sera finalement lorsque l'objet sera récupéré. (Voir ici .) Actuellement, Python est implémenté de sorte qu'il se produit dès qu'il n'y a plus de référence à un objet. Mais il est facile de propager accidentellement des références à un objet, et l'exécution de Python peut changer.
Pensez également à l'entretien à long terme. Il n'y a pas de référence à long terme maintenant, mais que se passe-t-il en 6 mois lorsque vous devez modifier le code pour qu'il y ait une référence? Et si quelqu'un d'autre le fait? La personne qui effectue le changement peut ne pas penser à passer à un
with
bloc car il n'y en a pas déjà un. Faites du nettoyage de vos ressources une habitude et vous aurez beaucoup moins de problèmes avec cela.Voulez-vous vraiment lier votre code aux détails d'implémentation de la récupération de place? Voulez-vous avoir constamment à réfléchir à la possibilité de propager accidentellement une référence via une exception? Non, non. Imaginez si cela s'est produit lorsque le script a été invoqué dans ArcMap. L'utilisateur serait obligé de fermer l'ensemble du processus juste pour libérer le fichier. Alors ne vous mettez pas dans cette position. Libérez la ressource explicitement. L'enregistrement d'une ligne de code ne vaut pas les risques de problèmes qu'elle peut causer. Les gestionnaires de contexte sont le mécanisme standard pour acquérir et libérer des ressources en Python, et ils le font très bien.
L'essentiel est que ne pas le publier explicitement est une mauvaise idée.
Bien entendu, cela suppose que le code a une certaine possibilité d'affecter quelqu'un d'autre, comme le mettre dans un script que quelqu'un d'autre devra exécuter ou maintenir ou cela pourrait retarder la livraison de votre travail si vous devez fermer ArcMap complètement parce que vous ne peut pas enregistrer vos modifications. Si vous êtes le seul à être touché par un problème, alors par tous les moyens, allez à l'encontre des bonnes pratiques tout ce que vous voulez.
la source
Non, il n'est pas nécessaire de supprimer un
cursor
après l'avoir utilisé dans une compréhension. Acursor
est une instance d'une classe, qui est un objet (tout en python est un objet). Chaque session python a unnamespace
qui contient des références à tous les objets de la session - pensez-y comme un dictionnaire où les clés sont des références à chaque objet, et les valeurs sont les objets eux-mêmes. Lorsque le «nombre de références» - le nombre de clés qui se réfèrent à cet objet - tombe à zéro, l'objet est supprimé et la mémoire réallouée . Lorsque vous utilisez uncursor
dans une compréhension, il n'y a aucune référence à cet objet dans l'espace de noms. Une fois la compréhension terminée, l'objet sera supprimé.Il n'y a aucune entrée dans l'espace de noms, et donc pas besoin de supprimer quoi que ce soit. ESRI illustre également cette syntaxe dans l' exemple 2, ici .
Pour clarifier davantage, si vous exécutez:
Vous verrez un fichier .lock apparaître dans le répertoire (vérifiez votre explorateur de fichiers). La référence au curseur est
a
, ce qui rendra lecursor
(et donc le verrou) persistant jusqu'à ce qu'ila
soit supprimé. Ainsi, lorsque vous exécutez ensuite:L'entrée dans l'espace de noms sera supprimée et le verrou sera libéré (le fichier .lock disparaîtra). Si vous exécutez:
Soit vous ne verrez pas de fichier de verrouillage, soit il disparaîtra à la fin de la commande. Sans entrée dans l'espace de noms, le
cursor
n'est pas persistant.t
fait référence à la liste que vous venez de créer, pas à cellecursor
utilisée pour la créer.Pour résumer, vous n'avez qu'à vous soucier de les supprimer
cursors
lorsqu'ils ont une référence dans l'espace de noms (c'est-à-dire lorsque vous les avez affectés à une variable, commea
dans l'exemple ci-dessus).la source
Le verrouillage avec les curseurs arcpy.da est à peu près le même que le verrouillage avec les curseurs arcpy d'origine.
Après avoir testé votre code, et comme l'a souligné gberard, il n'y a aucune référence au curseur après la fin de la compréhension.
De plus, il n'y a aucun verrou sur la classe d'entités après la fin de la compréhension.
la source