利用 Python 分布工具 (distutils),可将包含“模型”和/或“脚本工具”的 Python 工具箱和自定义工具箱以 Python 模块的形式高效地分发给 ArcGIS 用户。构建和分布这些工具箱的过程始于 Python 模块的创建。本示例中将使用模块 foo.py。
foo.py
用于创建 Python 模块 foo 的示例代码:
import os
def hello():
print('Hello ' + os.getenv('username'))
为了正确地构建和分布模块,必须存在特定的目录结构。必须创建一个名为 foo 的目录,用于存储 foo 模块。由于分布要求存储 foo 模块的目录必须位于父目录中,因此需创建一个名为 src 的目录来保存 foo 目录和 foo 模块。该目录结构应为如下所示:

为使 foo 模块在导入后即可进行初始化并自动执行特定代码,需要 __init__.py 文件。__init__.py 就位后,用户就可以访问 foo 模块并导入所选的定义。
__init__.py
用于为 foo 创建 __init__.py 的示例代码:
from foo import hello
该目录结构现在应为如下所示:

在文件和目录结构就位后,即可通过 import foo 导入 foo 模块,也可调用和执行 foo.hello()。下一步是为 foo 模块构建分布包,这样就可以将其安装到 Python 站点包目录,以便共享。此操作通过编写 setup.py 脚本完成。
setup.py
用于创建 setup.py 的示例代码:
from distutils.core import setup
setup(name='foo',
version='1.0',
packages=['foo'],
package_dir={'foo': 'foo'},
)
setup.py 文件用于设置模块名称和版本,并将构建工具指向包目录。setup.py 文件应保存在 src 目录中。此时,该目录结构应为如下所示:

目录结构就位后,可在 src 目录中使用相应的操作系统命令提示符通过运行以下其中一个命令来为 foo 模块构建安装程序。本示例构建于 Windows OS 中。
Windows:
python setup.py bdist_wininst
Linux:
python setup.py bdist_rpm
Windows 构建器在 src 目录中创建 dist 和 build 目录。在 dist 目录中,将创建 foo-1.0.win32.exe。它是一个可执行文件,可对该文件进行分布以在 Windows 计算机上将 foo 模块安装到 Python 站点包目录中。除了运行可执行文件以安装 foo 模块之外,还可以直接从 build/lib 目录将 foo 目录复制到 Python 站点包目录中。如果存在禁止运行可执行文件的用户限制,那么将 foo 目录从 build/lib 目录复制到站点包目录与通过可执行文件进行安装所获得的效果相同。在 foo 模块安装或复制到站点包目录后,结构应为如下所示:

通过将自定义工具箱和/或 Python 工具箱直接添加到 ArcGIS 系统工具箱,可进一步执行本过程以扩展地理处理功能。作为系统工具箱,它可在 ArcGIS 的系统工具箱列表中进行存取,还可以具有为扩展 ArcPy 而创建的 ArcPy 包装。此外,自定义工具箱模块还可以利用 ArcGIS 系统工具箱中用于进行消息分配、语言帮助和响应本地化设置的固有方法。ArcGIS Desktop 将在 Python 站点包位置中进行搜索,以查看各个模块中是否存在名为 esri 的目录。esri 目录中含有自定义工具箱及其相关帮助文件。以下为适用于英语的目录结构:

自定义工具箱(.tbx 和 .pyt)位于 esri/toolboxes 目录中;如果使用脚本工具,该目录中还包含所有的支持脚本。esri/help/gp 目录中存储着自定义工具箱和工具的工具箱和工具元数据 (.xml)。工具箱的命名约定为 <工具箱别名>_toolbox.xml,各工具的命名约定为 <工具名称>_<工具箱别名>.xml。所有的地理处理消息 (.xml) 文件都放置在 esri/help/gp/messages 目录中。这些消息文件在 Python 工具箱中用于需要进行国际化的消息。工具箱和工具标注类别将覆盖位于 esri/help/gp/toolboxes 目录中的文件。可通过创建名为 SamplePythonToolbox 的新 Python 工具箱来演示通过 Python 模块扩展地理处理的整个过程。有关创建和使用 Python 工具箱的详细信息,请参阅创建新的 Python 工具箱。
SamplePythonToolbox.pyt
用于创建 Python 工具箱的示例代码:
import arcpy
import os
import foo
class Toolbox(object):
def __init__(self):
"""Define the toolbox (the name of the toolbox is the name of the
.pyt file)."""
self.label = "Toolbox"
self.alias = "SampleToolbox"
# List of tool classes associated with this toolbox
self.tools = [SampleTool]
class SampleTool(object):
def __init__(self):
"""Define the tool (tool name is the name of the class)."""
self.label = "Sample Tool"
self.description = ""
self.canRunInBackground = False
def getParameterInfo(self):
"""Define parameter definitions"""
params = None
return params
def isLicensed(self):
"""Set whether tool is licensed to execute."""
return True
def updateParameters(self, parameters):
"""Modify the values and properties of parameters before internal
validation is performed. This method is called whenever a parameter
has been changed."""
return
def updateMessages(self, parameters):
"""Modify the messages created by internal validation for each tool
parameter. This method is called after internal validation."""
return
def execute(self, parameters, messages):
"""The source code of the tool."""
messages.AddMessage(os.getenv("username") + " welcome to the sample tool")
foo.hello()
return
在 SamplePythonToolbox.pyt 中,foo 模块已导入,且 SampleTool 类的 execute 方法已从 foo 模块中调用 hello 函数。这是将自定义 Python 代码作为模块进行分布并通过 ArcGIS 地理处理工具显示其功能的有效方法。在完成 SamplePythonToolbox.pyt 的创建并通过元数据(已在项目描述快捷菜单中对该元数据进行编辑)为工具箱配置了侧面板帮助之后,或在创建了编译的自定义帮助文件 (.chm) 之后,必须从该文件的创建目录对该文件及其附带的 .xml 文件进行复制。使用 ArcCatalog 或目录 窗口将文件复制到存在于分布结构中的 esri/toolboxes 目录。esri 目录和文件布局应为如下所示:

新分布的目录结构应为如下所示:

为在分布中反映出这些更改,必须对 setup.py 文件进行编辑。
新 setup.py
用于加入 setup.py 目录更改的示例代码:
from distutils.core import setup
setup(name='foo',
version='1.0',
packages=['foo'],
package_dir={'foo': 'foo'},
package_data={'foo': ['esri/toolboxes/*.*']},
)
新 setup.py 与原始 setup.py 中只有一行存在差异,该行将 esri 目录中找到的附加数据添加到包。现在,在执行并安装 foo 模块的构建器后,将在 Python 站点包目录中创建以下目录结构:

使用 ArcGIS Desktop 和 Python 分布工具 (Distutils),可以构建并安装程序包以通过自定义工具箱中的自定义工具来扩展地理处理,可在 ArcGIS 系统工具箱中查看并执行这些自定义工具箱。这些就是针对英语进行分布所需的全部内容。国际化主题中展开了地理处理扩展过程,用以使用与 Esri 相同的方法来打包模块以针对除英语外的其他语言进行分布。