抢先版本:
在您的计算机上成功运行的大部分 Python 脚本工具在另外一台计算机上解包时将成功打包和运行 - 您完全无需修改该脚本。 但如果出现问题,则可能是由于脚本使用了硬编码数据路径,或在导入您自行开发的 Python 模块时使用了 import 语句而导致的。
如何查找脚本中的数据
无论何时共享结果,无论共享为包还是服务,结果都会引用一个脚本工具,对该脚本工具进行扫描即可发现在脚本中使用的所有数据。 找到数据路径后,会将其合并到包中所包含的临时文件夹中。
当扫描脚本时,会对用于 Python 变量或作为函数参数的每个加引号的字符串(无论是单引号还是双引号)进行测试,以查看是否存在数据路径。 在这种情况下,数据是指地图图层、文件夹、文件或地理数据集,例如要素类、shapefile、地理数据库或图层文件。
出于讨论目的,我们只关注用作地理处理工具或路径(引用了其他 Python 模块)输入的数据。 输出数据也将一同合并。
在脚本中找到加引号的字符串后,按如下问题测试是否存在数据:
- 该字符串是否指代地图图层?
- 字符串中是否包含数据的绝对路径,如 e:\Warehousing\ToolData\SanFrancisco.gdb\streets?
- 可以找到相对于脚本位置的字符串参考数据吗? 脚本位置是包含脚本的文件夹。
- 如果脚本嵌入在工具箱中,其位置是包含工具箱的文件夹。
- 如果脚本位于 Python 工具箱中,则其位置是包含 Python 工具箱的文件夹。
这些测试按顺序依次进行。 如果通过测试,数据存在,将会对数据进行合并。
注:
合并文件夹时,只会复制文件夹中的文件和地理数据库,不会复制子文件夹。 有些地理数据集(例如,文件地理数据库、栅格和 TIN),从技术上讲它们是文件夹,但它们也是地理数据集,所以也将被复制。 如果文件夹包含图层文件,则该图层文件所引用的所有数据也将被合并,以保证脚本中的任何 arcpy.mp 例程都能够获取对引用数据的访问权限。
提示:
鉴于文件夹的合并方式,应避免在文件夹中夹杂工具不可能用到的大数据集和文件,因为这会增加不必要的数据打包量。
示例
下面示例是以该文件夹结构为基础的:

相对路径和文件夹
以下查找相对于脚本位置的数据的技术是一种常用方式。 以下脚本代码位于上图所示的脚本文件夹中,仅供参考。 ToolData 文件夹包含 SanFrancisco.gdb。 SanFrancisco.gdb 中是一个名为 Streets 的要素类。 在如下代码示例中,到 ToolData 文件夹的路径是相对于脚本位置(Scripts 文件夹)构建的。
import arcpy
import os
import sys
# Get the pathname to this script, then strip off the
# script file name to yield the containing folder
#
scriptPath = sys.path[0]
thisFolder = os.path.dirname(scriptPath)
# Construct paths to ../ToolData/SanFrancisco.gdb/Streets and
# ../ToolData/Warehouse.lyr
#
toolDataPath = os.path.join(thisFolder, "ToolData")
streetFeatures = os.path.join(toolDataPath, "SanFrancisco.gdb", "Streets")
streetLyr = os.path.join(toolDataPath, "Warehouse.lyr")
在以上代码中,将会测试字符串“ToolData”(os.path.join 函数的参数),以确认其是否存在。 在本例中,存在相对于脚本位置的名为 ToolData 的文件夹。 将合并 ToolData 文件夹 - 其全部内容(不包括上述子文件夹)将被打包。
请注意,复制的是文件夹内容,而非单个文件。 例如,在以上代码中,会构建数据集路径 e:/Warehousing/ToolData/SanFrancisco.gdb/Streets。 合并过程不是单独的而是仅复制 Streets 数据集 - 复制整个 ToolData 文件夹。
地理数据集的绝对路径
如以下代码示例所示,绝对路径以盘符开头,如 e:/。
streetFeatures = 'e:/Warehousing/ToolData/SanFrancisco.gdb/Streets'
在以上代码中,Streets 数据集及其所依赖的全部其他数据(如关系类和域)都将被合并。
混合示例
toolDataPath = r'e:\Warehousing\ToolData'
warehouseLyr = os.path.join(toolDataPath, "Warehouse.lyrx")
在上述代码中,将合并 ToolData 文件夹的全部内容。 由于合并了文件内容(不包括子文件夹),Warehouse.lyrx 也将与 Warehouse.lyrx 所引用的数据一起被合并。
正斜线与反斜线
Windows 约定使用反斜线 (\) 作为路径中的分隔符。 UNIX 系统使用正斜线 (/)。
注:
ArcGIS 可将正斜线和反斜线转换成相应的操作系统约定。
脚本中的反斜线
诸如 Python 等基于 UNIX 的和类似 C 语言的编程语言将反斜线 (\) 视为转义字符。 例如,\t 表示制表符。 由于路径可以包含反斜线,因此必须防止将反斜线用作转义字符。 建议您使用 r 指令将路径转换成 Python 原始字符串,如下所示。 由此会指示 Python 忽略反斜线。
thePath = r"E:\data\telluride\newdata.gdb\slopes"导入其他 Python 模块
您的脚本可能会导入您开发的其他脚本。 例如,以下代码显示了如何导入名为 myutils 的 Python 模块,其位于与父脚本相同的目录中,包含一个名为 getFIDName 的例程。
import arcpy
import myutils
inFeatures = arcpy.GetParameterAsText(0)
inFID = myutils.getFIDName(inFeatures)
遇到 import 语句时,将按照以下顺序定位脚本:
- 与脚本相同的文件夹。 如果脚本嵌入到工具箱中,将使用包含工具箱的文件夹。
- 系统 PYTHONPATH 变量所引用的文件夹。
- 系统 PATH 变量所引用的所有文件夹。
导入引用模块的另一项技术是使用 sys.path.append 方法。 由此可设置相应文件夹的路径,该文件夹包含必须导入的脚本。
import arcpy
import sys
import os
# Append the path to the utility modules to the system path
# for the duration of this script.
#
myPythonModules = r'e:\Warehousing\Scripts'
sys.path.append(myPythonModules)
import myutils # a Python file within myPythonModules
在上述代码中,请注意,sys.path.append 方法需要一个文件夹作为参数。 由于 'e:\Warehousing\Scripts' 是一个文件夹,因此将合并文件夹的全部内容。 复制文件夹内容的规则在此同样适用 - 文件夹中的所有内容(非地理数据集的子文件夹除外)都将被复制。
注:
不会为项目数据或导入的模块而扫描文件夹内的 Python 脚本。
工具验证代码
如果您具有编写脚本工具的经验,则可提供自定义工具验证逻辑。 通过 Python 验证逻辑,并扫描投影数据和模块的验证代码,就像其他 Python 脚本一样。 例如,您的验证逻辑可能会打开一个包含投影文件 (.prj) 的文件夹(例如 d:\approved_projections),以建立一个空间参考的选择列表,用户可以在运行您的工具时从中进行选择。 此文件夹不是工具参数;它是工具验证脚本内使用的数据路径。 以上对 Python 脚本描述的规则这里也适用,结果是 d:\approved_projections 文件夹会被整合并包括在包中。
第三方库
不会将第三方模块(即不是核心 Python 安装的任何模块)整合。 您必须确保模块在计算机上安装的位置就是解包的位置。 您应该提供针对您工具的文档和指定了所需第三方模块的包。 这并不适用于随 ArcGIS 一同安装的第三方模块,包括 Numpy、Matplotlib 以及 Pandas 等。