Techniques de partage des scripts Python
Voici quelques techniques que vous pouvez utiliser lors du partage de vos scripts Python avec d'autres.
Recherche de données par rapport à l'emplacement du script
Votre script devra peut-être utiliser ce que les programmeurs appellent des chemins d'accès fixes, à savoir des chemins d'accès à des données existantes et qui ne sont pas transmises en tant qu'argument. Par exemple, vous pouvez être amené à définir la propriété de symbologie de votre paramètre en sortie sur un fichier de couches existant ou à découper vos données selon un jeu de données connu.
Si vous partagez votre outil avec d'autres, vous devez vous assurer que votre script peut trouver les données dont il a besoin. Une méthode efficace pour ceci consiste à utiliser la structure de dossiers ToolShare et à placer vos données de projet dans le dossier ToolData et vos scripts dans le dossier Scripts. Si vous suivez ce modèle, vous pourrez toujours trouver vos données par rapport à l'emplacement de votre script.
Lorsque votre script est exécuté, il est possible de trouver le chemin au script à l'aide du code suivant :
scriptPath = sys.path[0]
Une fois cet emplacement connu, vous pouvez trouver vos données de projet par rapport à cet emplacement. L'extrait de code suivant illustre cela :
import arcpy import os import sys # Get the pathname to this script # scriptPath = sys.path[0] arcpy.AddMessage("Script folder: " + scriptPath) # Get the pathname to the ToolShare folder # toolSharePath = os.path.dirname(scriptPath) arcpy.AddMessage("ToolShare folder: " + toolSharePath) # Now construct pathname to the ToolData folder # toolDataPath = os.path.join(toolSharePath, "ToolData") arcpy.AddMessage("ToolData folder: " + toolDataPath) # Create the pathname to the parks feature class found in the ToolData folder # parkPath = os.path.join(toolDataPath, "Project.gdb/Parks") arcpy.AddMessage("Parks feature class: " + parkPath)
Si vous incorporez votre code de script, sys.path[0] renvoie l'emplacement de la boîte à outils (qui correspond à l'emplacement du code).
Recherche d'un espace de travail temporaire
Si vous créez des données temporaires dans votre script, il vous faut un espace de travail temporaire où vous pouvez créer puis supprimer ultérieurement vos données temporaires.
Voici quelques éléments à ne pas oublier au sujet de la recherche d'un espace de travail temporaire :
- Vous avez besoin d'une autorisation en écriture sur l'espace de travail.
- Si l'environnement de géotraitement d'espace de travail temporaire est défini, utilisez-le ; vous devez supposer qu'il a été défini intentionnellement par l'utilisateur sur un emplacement accessible en écriture. Dans le cas d'un service de géotraitement s'exécutant sur un serveur ArcGIS Server, l'espace de travail temporaire sera automatiquement défini par ArcGIS Server dans un dossier spécifique, accessible en écriture.
- Soyez prudent lorsque vous utilisez l'environnement d'espace de travail courant comme espace de travail temporaire ; il peut s'agir d'une base de données distante or vous ne voulez jamais utiliser une base de données distante comme emplacement temporaire, car la surcharge liée à la communication avec la base de données distante l'emporte sur l'objectif visant à créer, écrire et supprimer rapidement les données temporaires.
- Si l'environnement d'espace de travail temporaire n'a pas été défini, vous devez trouver un emplacement accessible en écriture. Si c'est le cas, plusieurs options sont possibles :
- Si vous utilisez la structure de dossiers ToolShare, vous pouvez utiliser scratch.gdb dans le dossier Scratch. Si vous pratiquez une programmation défensive, vous devez vérifier que scratch.gdb existe (l'utilisateur peut l'avoir supprimé).
- Si l'un de vos paramètres de script est un jeu de données en sortie, tel qu'une classe d'entités, vous pouvez supposer sans risque que vous possédez l'autorisation d'écrire dans l'emplacement du jeu de données en sortie, et vous pouvez l'utiliser comme espace de travail temporaire. Toutefois, vous devez vérifier si l'emplacement est un jeu de données d'entité ou une base de données distante. (Comme mentionné ci-dessus, vous ne voulez pas utiliser une base de données distante comme emplacement temporaire, car la surcharge liée à la communication avec la base de données distante l'emporte sur l'objectif visant à créer, écrire et supprimer rapidement les données temporaires.)
- Lorsque tout le reste a échoué, vous pouvez utiliser le répertoire système temp.
- Les classes d'entités incluses dans des espaces de travail de fichier de formes et de géodatabase personnelle ont une taille limitée à deux giga-octets. Bien que deux giga-octets représentent un volume important de données, cela reste une limite. Un espace de travail de géodatabase fichier a une limite par défaut d'un téraoctet (1 024 Go) pour un jeu de données. Si vous pensez que vos jeux de données temporaires peuvent dépasser 2 Go, utilisez une géodatabase fichier comme espace de travail temporaire.
- Utilisez la fonction CreateScratchName pour créer un nom de jeu de données unique dans votre espace de travail temporaire.
L'exemple de code suivant montre une application très défensive de la recherche d'un espace de travail temporaire. Ce code :
- n'utilise pas l'espace de travail courant comme espace de travail temporaire, mais peut être aisément modifié pour cela ;
- suppose que vous utilisez la structure de dossiers ToolShare ;
- tente de trouver et d'utiliser une géodatabase fichier et utilise un espace de travail de fichier de formes en dernier ressort.
import arcpy from arcpy import env import sys import os def getScratchWorkspace(outDataset): # outDataSet is assumed to be the full pathname to a dataset. Typically, # this would be a tool's output parameter value. # # Get the scratch workspace environment. If it's set, just return it. # scratchWS = env.scratchWorkspace if scratchWS: return scratchWS # Let's go fishing... # # If you're using the ToolShare folder structure, look for scratch.gdb in # the Scratch folder. # scriptPath = sys.path[0] toolSharePath = os.path.dirname(scriptPath) scratchWS = os.path.join(toolSharePath, "Scratch/scratch.gdb") if not arcpy.Exists(scratchWS): scratchWS = "" # No scratch workspace environment and no scratch.gdb in the ToolShare folder # if not scratchWS: # Get the workspace of the output dataset (if any passed in) # by going up one level # if outDataset: scratchWS = os.path.dirname(str(outDataset)) # If this isn't a workspace, go up another level and # test again. # desc = arcpy.Describe(scratchWS) if desc.dataType.upper() <> "WORKSPACE": scratchWS = os.path.dirname(scratchWS) desc = arcpy.Describe(scratchWS) if desc.dataType.upper() <> "WORKSPACE": scratchWS = "" # If we have a workspace, make sure it's not a remote (SDE) database. # If it is remote, set workspace to the system temp directory. # # If we don't have a workspace, just set it to the system temp directory. # usingTemp = False if scratchWS: desc = arcpy.Describe(scratchWS) if desc.workspaceType.upper() == "REMOTEDATABASE": scratchWS = arcpy.GetSystemEnvironment("TEMP") usingTemp = True else: scratchWS = arcpy.GetSystemEnvironment("TEMP") usingTemp = True # If we're using the system temp directory (a shapefile workspace), look # for a scratch file geodatabase. If it exists, use it. If it doesn't, # create it. # if usingTemp: scratchWS = os.path.join(scratchWS, "scratch.gdb") if arcpy.Exists(scratchWS): return scratchWS else: arcpy.CreateFileGDB_management(arcpy.GetSystemEnvironment("TEMP"), "scratch.gdb") return scratchWS # Main demonstration routine # One optional input parameter, a feature class. # aDatasetpath = arcpy.GetParameterAsText(0) scratch = getScratchWorkspace(aDatasetpath) arcpy.AddMessage("Scratch workspace: " + scratch) # Create a scratch feature class in the scratch workspace # scrname = arcpy.CreateScratchName("temp", "","featureclass", scratch) arcpy.AddMessage("Scratch feature class is: " + scrname) arcpy.CreateFeatureclass_management(scratch, os.path.basename(scrname), "point") arcpy.AddMessage(arcpy.GetMessages())
Partage de modules Python
Comme tout langage de programmation moderne, Python vous permet d'appeler des routines présentes dans d'autres scripts Python. Au fur et à mesure que vous développerez du code Python, vous voudrez probablement développer des routines Python à partager entre des scripts. L'objectif de cette section est de vous montrer brièvement comment partager des routines et de vous donner assez d'informations pour que vous puissiez rechercher et implémenter efficacement le partage de routines, en commençant par le site Web Python (http://www.python.org).
Voici le contenu d'un script, helloworld.py :
def dosomething(): print "Hello world" def somethingelse(): print "Goodbye world"
Voici le contenu d'un script, main.py :
import sys, os, helloworld helloworld.dosomething() helloworld.somethingelse()
Le script main.py importe le module helloworld (un nom de module correspond à un nom de script sans l'extension .py), en plus des modules sys et os. Notez que l'extension .py sur helloworld n'est pas requise (et n'est pas en fait autorisée).
Le script helloworld.py implémente deux routines (à l'aide de l'instruction def) : dosomething, qui imprime le message "Hello world" omniprésent et somethingelse, qui imprime le message "Goodbye world", moins connu. Lorsque le script main.py s'exécute, il appelle ces deux routines qui imprimeront "Hello world" et "Goodbye world".
Les deux modules montrés ci-dessus sont exempts de plusieurs éléments, tels que l'importation du module arcpy, la récupération d'environnements de géotraitement, la gestion des erreurs et des éléments similaires. Ces rubriques sont tout couverts dans Présentation rapide de Python.
Emplacement où Python recherche des modules
Lorsque main.py est exécuté, la directive import indique à Python de rechercher un fichier nommé helloworld.py dans sa liste de chemins de répertoires système. Le premier emplacement inspecté par Python correspond au répertoire courant, le répertoire où se trouve le script contenant la directive import (dans ce cas, main.py). Vous pouvez afficher la liste de ces chemins dans la fenêtre interactive de PythonWin avec :
import sys sys.path
Vous ne pouvez pas entrer un chemin d'accès dans la directive import, tel que
import E:\SharedScripts\helloworld
A la place, vous devez modifier la liste des répertoires où Python recherche des modules. Cette liste de répertoires est contenue dans le paramètre d'environnement Windows appelé PYTHONPATH, qui est installé par ArcGIS. Pour modifier ce paramètre, procédez comme suit :
- Dans le menu Démarrer de Windows, cliquez sur Paramètres > Panneau de configuration.
- Localisez et ouvrez le fichier Système.
- Cliquez sur l'onglet Avancé, puis cliquez sur Variables d'environnement.
- Sous Variables système, faites défiler l'affichage jusqu'à la variable PYTHONPATH et cliquez dessus pour la sélectionner.
- Si la variable PYTHONPATH n'existe pas, cliquez sur Nouveau. Dans la zone de texte Nom de la variable :, entrez PYTHONPATH.
- Dans la zone de texte Valeur de la variable :, entrez <répertoire installation ArcGIS>\bin;<répertoire installation ArcGIS\arcpy (par exemple, C:\Program Files\ArcGIS\Desktop10.0\bin;C:\Program Files\ArcGIS\Desktop10.0\arcpy).
- Cliquez sur OK.
- Si la variable PYTHONPATH existe, cliquez sur Modifier.
La variable PYTHONPATH doit contenir <répertoire installation ArcGIS>\bin;<répertoire installation ArcGIS\arcpy comme première entrée. Il s'agit de l'emplacement du module arcgisscripting. Vous pouvez ajouter des chemins d'accès supplémentaires aux répertoires contenant vos modules Python. Les chemins d'accès sont séparés par des points-virgules et il ne doit pas y avoir d'espaces autour des points-virgules.
Vous pouvez également ajouter un chemin d'accès dans votre code avec :
sys.path.append("e:\sharedmodules")
Partage de modules Python
Si vous fournissez des outils de script à d'autres utilisateurs et que les scripts importent d'autres modules, vous avez deux possibilités :
- Tous les scripts résident dans le même répertoire.
- Vous indiquez aux utilisateurs d'installer les modules supplémentaires quelque part dans leur système et de modifier la variable PYTHONPATH.
L'utilisation de sys.path.append() n'est pas recommandée, car elle nécessite la modification du code Python par les utilisateurs.
Chemins d'accès et caractère d'échappement
Les langages de programmation qui ont leur racine dans UNIX et le langage de programmation C, comme Python, utilisent la barre oblique inverse (\) comme caractère d'échappement. Par exemple, \n permet d'insérer un retour chariot lors de l'écriture d'un texte en sortie et \t permet d'insérer un caractère de tabulation. Si un chemin d'accès dans votre script utilise la barre oblique inverse comme séparateur, Python l'analysera et remplacera \n par un retour chariot et \t par une tabulation. (Il existe d'autres séquences de caractères d'échappement que \n et \t.)
La méthode la plus simple de se préserver de ceci consiste à convertir les chemins d'accès en chaînes brutes Python à l'aide de la "directive r, comme illustré ci-dessous. Cela indique à Python d'ignorer les barres obliques inverses.
thePath = r"E:\data\teluride\newdata.gdb\slopes"
Pour en savoir plus sur la définition de chemins d'accès à des données
Vérification des licences
Si votre script utilise des extensions ou s'appuie sur des outils non disponibles au niveau de produit ArcView ou ArcEditor, vous devez commencer par vérifier les licences et les niveaux de produit.
Pour en savoir plus la vérification des licences dans les scripts