Técnicas para compartir secuencias de comandos de Python
A continuación, encontrará algunas técnicas que puede utilizar a la hora de compartir las secuencias de comando de Python con otros usuarios.
Buscar datos relativos a la ubicación de la secuencia de comandos
Es probable que la secuencia de comandos deba utilizar lo que los programadores denominan "rutas preprogramadas", que son rutas de datos existentes que no se transfieren en forma de argumento. Por ejemplo, es posible que sea necesario establecer la propiedad de simbología del parámetro de salida en un archivo de capa existente, o bien recortar los datos en un dataset conocido.
Si comparte la herramienta con otros usuarios, deberá asegurarse de que la secuencia de comandos puede encontrar los datos que ésta requiera. Esto se puede realizar utilizando la estructura de carpetas ToolShare y colocando los datos de proyecto en la carpeta ToolData y las secuencias de comandos en la carpeta Secuencias de comandos. Si sigue este patrón, siempre podrá encontrar los datos relativos a la ubicación de la secuencia de comandos.
Cuando ejecute la secuencia de comandos, podrá averiguar la ruta a la secuencia de comandos de la siguiente forma:
scriptPath = sys.path[0]
Una vez se conozca la ubicación, podrá buscar los datos de proyecto relativos a esta ubicación. El siguiente fragmento de código lo demuestra:
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 incorpora el código de la secuencia de comandos, sys.path[0] volverá a la ubicación de la caja de herramientas (que es donde se halla el código).
Buscar un espacio de trabajo temporal
Si crea datos temporales en la secuencia de comandos, necesitará un espacio de trabajo temporal en el que poder crear y posteriormente borrar los datos temporales.
A continuación, encontrará algunos aspectos que deberá tener en cuenta a la hora de buscar un espacio de trabajo temporal:
- Necesita tener permisos de escritura en el espacio de trabajo.
- Si el entorno de geoprocesamiento del espacio de trabajo temporal está configurado, utilícelo (el usuario lo ha establecido deliberadamente en una ubicación editable). En el caso de que haya un servicio de geoprocesamiento en ejecución en un servidor de ArcGIS, ArcGIS Server establecerá automáticamente el espacio de trabajo temporal en una carpeta editable específica.
- Tenga cuidado al utilizar el entorno de espacio de trabajo actual como espacio de trabajo temporal, pues podría tratarse de una base de datos remota, y no se recomienda utilizar este tipo de base de datos como ubicación temporal, ya que la sobrecarga de comunicación con la base de datos remota impide la posibilidad de crear, escribir y borrar datos temporales rápidamente.
- Si el entorno de espacio de trabajo temporal no está configurado, deberá buscar una ubicación editable. De darse este caso, existen algunas opciones disponibles:
- Si está utilizando la estructura de carpetas ToolShare, puede utilizar scratch.gdb de la carpeta Temporal . Si está practicando programación defensiva, deberá comprobar que existe scratch.gdb, ya que el usuario podría haberlo eliminado.
- Si uno de los parámetros de la secuencia de comandos es un dataset de salida, como por ejemplo una clase de entidad, puede asumir con seguridad que dispone de permisos de escritura en la ubicación del dataset de salida y puede además utilizarlo como espacio de trabajo temporal. No obstante, deberá comprobar si la ubicación es un dataset de entidades o una base de datos remota. (Como se ha mencionado anteriormente, no se recomienda utilizar una base de datos remota como ubicación temporal, ya que la sobrecarga de comunicación con la base de datos remota impide la posibilidad de crear, escribir y borrar datos temporales rápidamente).
- Cuando falle todo lo demás, siempre podrá utilizar el directorio temp del sistema.
- Las clases de entidad de los espacios de trabajo de la geodatabase personal y de shapefile tienen un tamaño límite de dos gigabytes. Aunque en dos gigabytes hay espacio para muchos datos, no deja de ser un límite. Un espacio de trabajo de una geodatabase de archivos tiene un límite predeterminado de un terabyte (1024 gigabytes) para un dataset. Si cree que los datasets temporales podrían superar los dos gigabytes, utilice una geodatabase de archivos como espacio de trabajo temporal.
- Utilice la función CreateScratchName para crear un nombre de dataset único en el espacio de trabajo temporal.
En el siguiente código de ejemplo se muestra una implementación muy defensiva de la búsqueda de un espacio de trabajo temporal. Este código
- no utiliza el espacio de trabajo actual como espacio de trabajo temporal, pero es posible modificarlo fácilmente para que así lo haga
- asume que el usuario utiliza la estructura de carpetas ToolShare
- intenta encontrar y utilizar una geodatabase de archivos, y utilizará un espacio de trabajo de shapefile como último recurso
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())
Compartir módulos de Python
Como ocurre en todo lenguaje moderno de programación, Python permite utilizar las rutinas encontradas en otras secuencias de comandos Python. A medida que vaya desarrollando el código Python, podrá desarrollar también rutinas Python con el fin de compartirlas entre las secuencias de comandos. La finalidad de este apartado radica en mostrar, de forma resumida, cómo puede compartir rutinas y proporcionarle la información suficiente para que pueda examinar e implementar con efectividad el uso compartido de rutinas, empezando por el sitio web oficial de Python (http://www.python.org).
A continuación, se muestra el contenido de una secuencia de comandos, helloworld.py:
def dosomething(): print "Hello world" def somethingelse(): print "Goodbye world"
A continuación, se muestra el contenido de una secuencia de comandos, main.py:
import sys, os, helloworld helloworld.dosomething() helloworld.somethingelse()
La secuencia de comandos main.py importa el módulo helloworld (el nombre de un módulo es igual al nombre de la secuencia de comandos exceptuando la extensión .py) junto con los módulos sys y os. Tenga en cuenta que la extensión .py en helloworld no es necesaria (y, de hecho, no está permitida).
La secuencia de comandos helloworld.py implementa dos rutinas (mediante la declaración def) llamadas dosomething, que imprime el ubicuo "Hello world", y somethingelse, que imprime el menos ubicuo "Goodbye world". Cuando main.py se ejecute, utilizará estas dos rutinas, que imprimirán "Hello world" y "Goodbye world".
Los dos módulos mostrados anteriormente carecen de un gran número de aspectos, tales como la importación de arcpy, la recuperación de entornos de geoprocesamiento, el manejo de errores, etc. Estos temas se tratan en la sección Recorrido rápido por Python.
Dónde busca Python los módulos
Cuando main.py se ejecute, la directiva de importación provocará que Python busque un archivo llamado helloworld.py en su listado de rutas de directorios del sistema. El primer lugar en el que Python buscará será el directorio actual, que es el mismo directorio en el que se encuentra la secuencia de comandos que incluye la directiva de importación (en este caso, main.py). Puede visualizar una lista de estas rutas en la ventana interactiva de PythonWin con:
import sys sys.path
No se puede introducir una ruta en la directiva de importación, como por ejemplo
import E:\SharedScripts\helloworld
En su lugar, deberá modificar el listado de directorios en el que Python busca los módulos. Este listado de directorios se encuentra en una configuración de entorno de Windows llamada PYTHONPATH, que instala ArcGIS. Para modificar esta configuración, realice lo siguiente:
- En el menú Inicio de Windows, haga clic en Ajustes > Panel de control.
- Localice y abra el archivo Sistema.
- Haga clic en la ficha Opciones avanzadas y, a continuación, haga clic en Variables de entorno.
- En Variables del sistema, desplácese hasta la variable PYTHONPATH y haga clic en ella para seleccionarla.
- Si la variable PYTHONPATH no existe, haga clic en Nuevo. En el cuadro de texto Nombre de variable: introduzca PYTHONPATH.
- En el cuadro de texto Valor de variable: introduzca <ArcGIS install directory>\bin;<ArcGIS install directory\arcpy (por ejemplo, C:\Program Files\ArcGIS\Desktop10.0\bin;C:\Program Files\ArcGIS\Desktop10.0\arcpy).
- Haga clic en Aceptar.
- Si existe la variable PYTHONPATH, haga clic en Editar.
En el contenido de PYTHONPATH debe constar <ArcGIS install directory>\bin;<ArcGIS install directory\arcpy como primera entrada. Este es el lugar en el que se encuentra el módulo arcgisscripting. Puede incorporar más rutas a directorios que contengan módulos Python. Las rutas aparecen separadas con punto y coma, y no debe haber ningún espacio en torno a las mismas.
También puede incorporar una ruta en su código con
sys.path.append("e:\sharedmodules")
Compartir módulos de Python
Si suministra herramientas de secuencias de comandos a otros usuarios y las secuencias de comandos importan otros módulos, dispone de dos opciones:
- Todas las secuencias de comandos se encuentran en un mismo directorio.
- Dar la orden a los usuarios para que instalen los módulos adicionales en cualquier ruta de sus equipos y modifiquen la variable PYTHONPATH.
No se recomienda el uso de sys.path.append(), ya que requiere que los usuarios modifiquen el código Python.
Rutas y el carácter de escape
Los lenguajes de programación que tienen sus raíces en UNIX y en el lenguaje de programación C, como es el caso de Python, utilizan las barras invertidas (\) como el carácter de escape. Por ejemplo, se utiliza \n para insertar un retorno de carro al escribir texto de salida, y \t para insertar un carácter de tabulación. Si una ruta de la secuencia de comandos utiliza barras invertidas como separadores, Python la explorará y aplicará un retorno de carro cuando localice un \n y una tabulación para un \t. (Existen otras secuencias con caracteres de escape además de \n y \t).
El método más sencillo de evitar que ocurra algo así consiste en convertir las rutas en cadenas de caracteres originales de Python mediante la directiva r, como se muestra a continuación. Esto da la orden a Python de ignorar las barras invertidas.
thePath = r"E:\data\teluride\newdata.gdb\slopes"
Comprobar licencias
Si la secuencia de comandos utiliza extensiones o se vale de herramientas que no están disponibles en el nivel de producto de ArcView o ArcEditor, es necesario que compruebe primero las licencias y niveles de producto.
Más información acerca de comprobar licencias en secuencias de comandos