Suite

Gérer les variables d'environnement dans arcpy?


La documentation Arcpy semble suggérer que lors de l'écriture de scripts python qui utilisent/modifient des variables dansarcpy.env, vous devriez tout envelopper dans un tas deessayer/sauf/(enfin)boucles avec des types d'erreur personnalisés (qui sont généralement une mauvaise pratique, IMO).

Dans le cas ici, ils ne se prémunissent même pas contre les erreurs en laissant l'extension extraite :

import arcpy import arcpyproduction # Vérifier la licence de cartographie de production arcpy.CheckOutExtension("Foundation") # Définir les coordonnées de la carte, du bloc de données et de la géométrie du polygone [snip] # Créer une géométrie de polygone pour coordPair dans coordList : x, y = coordPair.split( "                                                                         Intégrer l’extension arcpy.CheckInExtension( "Fondation")

Je sais que ce n'est pas un risque énorme, mais il doit y avoir un meilleur moyen, non ?


J'aime utiliser les gestionnaires de contexte. En particulier, j'en ai trois pour

  • arcpy.env.espace de travail,
  • arcpy.env.overwriteSortie, et
  • arcpy.Check[In|Out]Extension

Ils sont:

class Extension(object): def __init__(self, name): self.name = name def __enter__(self): if arcpy.CheckExtension(self.name) == "Available": arcpy.CheckOutExtension(self.name) else: augmenter ValueError("la licence %s n'est pas disponible" % self.name) def __exit__(self, *args): arcpy.CheckInExtension(self.name) class OverwriteState(object): def __init__(self, overwrite): self. orig_state = arcpy.env.overwriteOutput self.new_state = bool(overwrite) def __enter__(self, *args, **kwargs): arcpy.env.overwriteOutput = self.new_state def __exit__(self, *args, **kwargs): arcpy.env.overwriteOutput = self.orig_state class WorkSpace(object): def __init__(self, path): self.orig_workspace = arcpy.env.workspace self.new_workspace = path def __enter__(self, *args, **kwargs): arcpy.env.workspace = self.new_workspace def __exit__(self, *args, **kwargs): arcpy.env.workspace = self.orig_workspace

Si votre version d'arcpy est suffisamment récente pour être sur Python 2.7, vous pouvez toutes les utiliser en même temps comme ceci :

avec Extension("3D"), OverwriteState(True), Workspace("c:/GrosMorne") : arcpy.HillShade_3d("WesternBrook", "wbrook_hill", 300) arcpy.Aspect_3d("WesternBrook", "wbrook_aspect")

Si vous êtes bloqué sur Python 2.6, c'est un peu plus moche :

avec Extension("3D") : avec OverwriteState(True) : avec : Workspace("c:/GrosMorne") : arcpy.HillShade_3d("WesternBrook", "wbrook_hill", 300) arcpy.Aspect_3d("WesternBrook", "wbrook_aspect ")

Ceux-ci protègent contre les erreurs dans le traitement que vous effectuez afin que les variables/extensions d'environnement soient ramenées à leur état d'origine, quelle que soit la manière dont le code dans leavecbloquer les sorties (par exemple, avec succès, en erreur, interrompu).

Cela ressemble à quelque chose comme ça :

arcpy.env.overwriteOutput = False print('Avant le gestionnaire de contexte : {}'.format(arcpy.env.overwriteOutput)) avec OverwriteState(True): print('À l'intérieur du gestionnaire de contexte : {}'.format(arcpy. env.overwriteOutput)) raise ValueError("arcpy est un mauvais moment") print('Après le gestionnaire de contexte : {}'.format(arcpy.env.overwriteOutput))

Production:

Avant le gestionnaire de contexte : False À l'intérieur du gestionnaire de contexte : Vrai -------------------------------------- ------------------------------------- ValueError Traceback (appel le plus récent en dernier) [snip] ValueError : arcpy est un mauvais moment --------------------------------------------- ------------------------------ Après le gestionnaire de contexte : Faux

Après avoir découvert certaines des qualités de la bibliothèque standard python, les gestionnaires de contexte simplifient :

import arcpy from contextlib import contextmanager @contextmanager def Extension(name): """ Utilisez en toute sécurité les extensions ArcGIS """ if arcpy.CheckExtension(name) == u"Available": status = arcpy.CheckOutExtension(name) yield status else: raise RuntimeError("La licence %s n'est pas disponible" % name) arcpy.CheckInExtension(name) @contextmanager def OverwriteState(state): """ Définissez temporairement la variable env "overwriteOutput". """ orig_state = arcpy.env. overwriteOutput arcpy.env.overwriteOutput = bool(state) yield state arcpy.env.overwriteOutput = orig_state @contextmanager def WorkSpace(path): """ Définir temporairement la variable env "workspace". """ orig_workspace = arcpy.env.workspace arcpy.env.workspace = chemin de rendement chemin arcpy.env.workspace = orig_workspace