Verfahren für die gemeinsame Verwendung von Python-Skripten
Im Folgenden werden eine Reihe von Verfahren aufgeführt, die Sie beim gemeinsamen Verwenden von Python-Skripten mit anderen verwenden können.
Suchen von Daten relativ zum Speicherort des Skripts
Möglicherweise müssen im Skript Pfadnamen verwendet werden, die von Programmierern als "hart kodiert" bezeichnet werden – Pfade zu vorhandenen Daten, die nicht als Argument übergeben werden. Beispielsweise kann es erforderlich sein, dass Sie die Symbologieeigenschaft des Ausgabeparameters auf eine vorhandene Layer-Datei festlegen oder die Daten auf ein bekanntes Dataset zuschneiden.
Wenn Sie das Werkzeug gemeinsam mit anderen verwenden, müssen Sie sicherstellen, dass das Skript die benötigten Daten finden kann. Dies können Sie gut mithilfe der "ToolShare"-Ordnerstruktur realisieren, in der Sie Ihre Projektdaten im Ordner ToolData und Ihre Skripte im Ordner Scripts platzieren. Wenn Sie sich an dieses Muster halten, können Sie die Daten immer relativ zum Speicherort des Skripts finden.
Wenn das Skript ausgeführt wird, kann der Pfad für das Skript wie folgt gesucht werden:
scriptPath = sys.path[0]
Wenn diese Position bekannt ist, finden Sie die Projektdaten relativ zu diesem Speicherort. Im folgenden Codeausschnitt wird dies demonstriert:
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)
Wenn Sie den Skriptcode einbetten, gibt sys.path[0] den Speicherort der Toolbox (d. h. den Speicherort des entsprechenden Codes) zurück.
Suchen eines Scratch-Workspace
Wenn Sie Scratch-Daten mit dem Skript erstellen, benötigen Sie einen Scratch-Workspace zum Erstellen und anschließenden Löschen der Scratch-Daten.
Im Folgenden werden einige Punkte aufgeführt, die Sie beim Suchen eines Scratch-Workspace beachten sollten:
- Sie benötigen Schreibberechtigungen für den Workspace.
- Wenn die Scratch-Workspace-Geoverarbeitungsumgebung festgelegt ist, verwenden Sie sie. Sie sollten davon ausgehen, dass sie vom Benutzer bewusst auf einen Speicherort mit Schreibberechtigungen festgelegt wurde. Bei einem Geoverarbeitungs-Service, der auf einem ArcGIS-Server ausgeführt wird, wird der Scratch-Workspace von ArcGIS Server auf einen bestimmten Ordner mit Schreibberechtigungen festgelegt.
- Gehen Sie mit Vorsicht vor, wenn Sie die derzeitige Workspace-Umgebung als Scratch-Workspace verwenden möchten, denn möglicherweise handelt es sich um eine Remote-Datenbank. Sie sollten niemals eine Remote-Datenbank als Scratch-Speicherort verwenden, da durch den zusätzlichen Aufwand für die Kommunikation mit der Datenbank Scratch-Daten nicht wie beabsichtigt schnell erstellt, geschrieben und gelöscht werden können.
- Wenn die Umgebungseinstellung für den Scratch-Workspace nicht festgelegt wurde, müssen Sie einen Speicherort mit Schreibberechtigung suchen. Wenn dies der Fall ist, gibt es eine Reihe von Optionen:
- Wenn Sie die "ToolShare"-Ordnerstruktur verwenden, können Sie die Datei scratch.gdb im Ordner Scratch verwenden. Wenn Sie defensiv programmieren, sollten Sie überprüfen, ob die Datei scratch.gdb vorhanden ist. Möglicherweise wurde sie vom Benutzer gelöscht.
- Wenn es sich bei einem der Skriptparameter um ein Ausgabe-Dataset handelt, z. B. eine Feature-Class, können Sie davon ausgehen, dass Sie über Schreibberechtigung für den Speicherort des Ausgabe-Datasets verfügen, und Sie können diesen als Scratch-Workspace verwenden. Sie müssen jedoch überprüfen, ob es sich bei dem Speicherort um ein Feature-Dataset oder eine Remote-Datenbank handelt. (Wie bereits erwähnt, sollten Sie keine Remote-Datenbank als Scratch-Speicherort verwenden, da der Zusatzaufwand für die Kommunikation mit der Datenbank dem Ziel entgegensteht, Scratch-Daten schnell zu erstellen, zu schreiben und zu löschen.)
- Wenn keine andere Möglichkeit besteht, können Sie immer auch das Verzeichnis temp verwenden.
- Feature-Classes in Shapefile- und Personal-Geodatabase-Workspaces weisen eine Größenbeschränkung von zwei Gigabyte auf. Obwohl es sich bei zwei Gigabyte um eine große Datenmenge handelt, stellt dies doch eine Einschränkung dar. Ein File-Geodatabase-Workspace verfügt über eine Standardbeschränkung von einem Terabyte (1024 Gigabyte) für ein Dataset. Wenn Sie vermuten, dass Ihre Scratch-Datasets zwei Gigabyte überschreiten könnten, verwenden Sie eine File-Geodatabase als Scratch-Workspace.
- Erstellen Sie mit der Funktion CreateScratchName einen eindeutigen Namen für das Dataset im Scratch-Workspace.
Im folgenden Codebeispiel wird eine sehr defensive Implementierung für das Suchen eines Scratch-Workspace veranschaulicht. Für diesen Code gilt Folgendes:
- Es wird nicht der aktuelle Workspace als Scratch-Workspace verwendet. Der Code kann jedoch leicht entsprechend geändert werden.
- Es wird davon ausgegangen, dass Sie die "ToolShare"-Ordnerstruktur verwenden.
- Es wird versucht, eine File-Geodatabase aufzufinden und zu verwenden. Als letzter Ausweg wird ein Shapefile-Workspace verwendet.
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())
Gemeinsames Nutzen von Python-Modulen
Wie in allen modernen Programmiersprachen können Sie auch in Python Routinen aus anderen Python-Skripten aufrufen. Je mehr Python-Code Sie entwickeln, desto größer wird die Wahrscheinlichkeit, dass Sie Python-Routinen für die gemeinsame Nutzung in mehreren Skripten entwickeln möchten. In diesem Abschnitt soll kurz dargestellt werden, wie Routinen gemeinsam genutzt werden können. Außerdem erhalten Sie einen hinreichenden Einblick in die effiziente Suche und Umsetzung der gemeinsamen Nutzung von Routinen, zuerst über die offizielle Python-Website (http://www.python.org).
Nehmen Sie an, dass das Skript "helloworld.py" folgenden Inhalt hat:
def dosomething(): print "Hello world" def somethingelse(): print "Goodbye world"
Nehmen Sie außerdem an, dass das Skript "main.py" folgenden Inhalt hat:
import sys, os, helloworld helloworld.dosomething() helloworld.somethingelse()
Das Skript main.py importiert das Modul "helloworld" (Modulnamen entsprechen den Skriptnamen ohne die Erweiterung ".py") wie auch die Module sys und os. Dabei ist die Erweiterung .py bei helloworld nicht erforderlich (und auch nicht zulässig).
Mit dem Skript helloworld.py werden (mit der def-Anweisung) zwei Routinen implementiert: "dosomething" gibt das unvermeidliche "Hello world" aus, somethingelse gibt das weit weniger verbreitete "Goodbye world" aus. Während der Ausführung von main.py werden die beiden Routinen aufgerufen und "Hello world" sowie "Goodbye world" ausgegeben.
In den oben dargestellten zwei Modulen fehlen viele wichtige Elemente, beispielsweise das Importieren des Moduls arcpy, das Abrufen von Geoverarbeitungsumgebungen, die Fehlerbehandlung usw. Diese Themen werden alle in Kurzer Überblick über Python behandelt.
Verzeichnisse, in denen Python Module sucht
Wenn main.py ausgeführt wird, weist die Import-Direktive Python an, in der Liste der Systemverzeichnispfade nach der Datei helloworld.py zu suchen. Python durchsucht zuerst das aktuelle Verzeichnis, also das Verzeichnis, in dem sich auch das Skript mit der Import-Direktive (hier main.py) befindet. Mit dem folgenden Befehl können Sie im interaktiven PythonWin-Fenster eine Liste der entsprechenden Pfade anzeigen:
import sys sys.path
In der Import-Direktive können keine Pfade wie im folgenden Beispiel eingegeben werden:
import E:\SharedScripts\helloworld
Stattdessen müssen Sie die Liste der Verzeichnisse ändern, die Python nach Modulen durchsucht. Diese Liste ist in der Windows-Umgebungseinstellung PYTHONPATH enthalten, die von ArcGIS eingerichtet wird. So ändern Sie diese Einstellung:
- Klicken Sie im Menü "Start" von Windows auf Einstellungen > Systemsteuerung.
- Suchen und öffnen Sie "System".
- Klicken Sie auf die Registerkarte Erweitert und dann auf Umgebungsvariablen.
- Führen Sie im Bereich Systemvariablen einen Bildlauf zur Variablen PYTHONPATH durch und markieren Sie sie.
- Wenn die Variable "PYTHONPATH" nicht vorhanden ist, klicken Sie auf Neu. Geben Sie PYTHONPATH in das Textfeld Variablenname ein.
- Geben Sie im Textfeld Variablenwert <ArcGIS-Installationsverzeichnis>\bin;<ArcGIS-Installationsverzeichnis>\arcpy ein (z. B. C:\Programme\ArcGIS\Desktop10.0\bin;C:\Programme\ArcGIS\Desktop10.0\arcpy).
- Klicken Sie auf OK.
- Wenn die Variable "PYTHONPATH" vorhanden ist, klicken Sie auf Bearbeiten.
Der erste Eintrag in PYTHONPATH sollte <ArcGIS-Installationsverzeichnis>\bin;<ArcGIS-Installationsverzeichnis>\arcpy lauten. Dort befindet sich das Modul "arcgisscripting". Sie können weitere Pfade für Verzeichnisse anhängen, in denen Python-Module enthalten sind. Als Trennzeichen zwischen Pfaden wird das Semikolon verwendet, vor und nach dem Semikolon dürfen keine Leerzeichen eingegeben werden.
Sie können auch im Code einen Pfad anfügen:
sys.path.append("e:\sharedmodules")
Gemeinsames Nutzen von Python-Modulen
Wenn Sie Skriptwerkzeuge für andere Benutzer bereitstellen und die Skripte andere Module importieren, bestehen zwei Möglichkeiten:
- Alle Skripte befinden sich im selben Verzeichnis.
- Sie fordern die Benutzer auf, die zusätzlichen Module an einem beliebigen Speicherort des Computers zu installieren und anschließend die Variable PYTHONPATH zu ändern.
Die Verwendung von sys.path.append() wird nicht empfohlen, da die Benutzer hierfür den Python-Code ändern müssten.
Pfade und das Escape-Zeichen
Programmiersprachen, deren Wurzeln in den Programmiersprachen UNIX und C liegen, z. B. Python, behandeln den umgekehrten Schrägstrich (\) als Escape-Zeichen. Mit \n wird bei der Ausgabe von Text z. B. ein Zeilenumbruch und mit \t ein Tabulatorzeichen eingefügt. Wenn in einem Pfad im Skript umgekehrte Schrägstriche als Trennzeichen verwendet werden, wird er von Python analysiert und \n wird durch einen Zeilenumbruch, \t durch einen Tabulator ersetzt. (Es gibt weitere Escape-Zeichenfolgen neben \n und \t.)
Die einfachste Möglichkeit, dies zu verhindern, ist das Konvertieren von Pfaden in Python-Raw-Strings mit der Direktive r, wie unten dargestellt. Hiermit wird Python angewiesen, umgekehrte Schrägstriche zu ignorieren.
thePath = r"E:\data\teluride\newdata.gdb\slopes"
Überprüfen von Lizenzen
Wenn im Skript Erweiterungen verwendet werden oder es auf Werkzeugen basiert, die auf der ArcView- oder ArcEditor-Produktstufe nicht verfügbar sind, müssen Sie zunächst Lizenzen und Produktstufen überprüfen.
Weitere Informationen zum Überprüfen von Lizenzen in Skripten