Techniques for sharing Python scripts |
|
|
Release 9.3
Last modified October 19, 2010 |
Print all topics in : "Sharing tools and toolboxes" |
The following are some techniques you can use when sharing your Python scripts with others.
Your script may need to use "hard-wired" pathnames—pathnames to project data that exists and is not passed as an argument. For example, you may need to set the symbology property of your output parameter to an existing layer file, or clip your data to a known dataset.
If you are sharing your tool with others, you need to make sure that your script can find the project data it needs. A good way to do this is to use the ToolShare folder structure and place your project data in the ToolData folder and your scripts in the Scripts folder. If you follow this pattern, then you can always find your data relative to the location of your script.
When your script is run, the pathname to the script can be found using the following:
scriptPath = sys.path[0]
import arcgisscripting, os, sys
gp = arcgisscripting.create(9.3)
# Get the pathname to this script
#
scriptPath = sys.path[0]
gp.AddMessage("Script folder: " + scriptPath)
# Get the pathname to the ToolShare folder
#
toolSharePath = os.path.dirname(scriptPath)
gp.AddMessage("ToolShare folder: " + toolSharePath)
# Now construct pathname to the ToolData folder
#
toolDataPath = toolSharePath + os.path.sep + "ToolData"
gp.AddMessage("ToolData folder: " + toolDataPath)
# Create the pathname to the parks feature class found in the ToolData folder
#
parkPath = toolDataPath + os.path.sep + "Project.gdb" + os.path.sep + "Parks"
gp.AddMessage("Parks feature class: " + parkPath)
If you create scratch data within your script, you need a scratch workspace where you can create and subsequently delete your scratch data.
Here are some things to keep in mind about finding a scratch workspace:
import arcgisscripting, sys, os
gp = arcgisscripting.create(9.3)
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 = gp.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 = toolSharePath + os.path.sep + "Scratch" + os.path.sep + "scratch.gdb"
if not gp.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 = gp.Describe(scratchWS)
if desc.DataType.upper() <> "WORKSPACE":
scratchWS = os.path.dirname(scratchWS)
desc = gp.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 = gp.Describe(scratchWS)
if desc.WorkspaceType.upper() == "REMOTEDATABASE":
scratchWS = gp.GetSystemEnvironment("TEMP")
usingTemp = True
else:
scratchWS = gp.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 = scratchWS + os.path.sep + "scratch.gdb"
if gp.Exists(scratchWS):
return scratchWS
else:
gp.CreateFileGDB_management(gp.GetSystemEnvironment("TEMP"), "scratch.gdb")
return scratchWS
# Main demonstration routine
# One optional input parameter, a feature class.
#
gp.LogHistory = True
aDatasetpath = gp.GetParameterAsText(0)
scratch = getScratchWorkspace(aDatasetpath)
gp.AddMessage("Scratch workspace: " + scratch)
# Create a scratch feature class in the scratch workspace
#
scrname = gp.CreateScratchName("temp", "","featureclass", scratch)
gp.AddMessage("Scratch feature class is: " + scrname)
gp.CreateFeatureClass(scratch, os.path.basename(scrname), "point")
gp.AddMessage(gp.GetMessages())
Like any modern programming language, Python allows you to call routines found in other Python scripts. As you develop more and more Python code, you'll probably want to develop Python routines to share among scripts. The purpose of this section is to briefly show you how you can share routines, and give you enough information that you can effectively research and implement sharing of routines, starting with the official Python Web site (http://www.python.org).
Here are the contents of a script, helloworld.py:
def dosomething():
print "Hello world"
def somethingelse():
print "Goodbye world"
import sys, os, helloworld helloworld.dosomething() helloworld.somethingelse()
import sys sys.path
import E:\SharedScripts\helloworld
sys.path.append("e:\sharedmodules")
Programming languages that have their roots in Unix and the C programming language, like Python, treat the backslash (\) as the escape character. For example, "\n" is used to insert a carriage return when writing text output; "\t" is used to insert a tab character. If a pathname in your script uses backslashes as the separator, Python will scan it and substitute a carriage return when it encounters a "\n" and a tab for a "\t". (There are other escape character sequences besides \n and \t.)
The easiest way to guard against this is to convert pathnames into Python rawstrings using the r directive, as shown below. This instructs Python to ignore backslashes.
thePath = r"E:\data\teluride\newdata.gdb\slopes"
If your script is using extensions or relies on tools that unavailable at the ArcView or ArcEditor product level, you need to first check for licenses and product levels.
Learn more about license checking in scripts
View lists of tools by license and product level