分享

搜罗全网!ArcGIS二次开发Python(arcpy)指南(八):ArcPy打包终极版

 GIS荟 2022-03-07

Note:对于 ArcPy 的打包是针对 ArcGIS 10.X 版本,请注意。

早在 2021年2月,我写了一篇 ArcPy 打包效果的演示文章《Python&ArcPy打包指北(上)》,其中展示了打包过程以及演示效果。

不过迟迟没有下一篇,今天终于可以把文章补全了,也将打包的技巧分享出去。

必要的解释

再往下讲的话有必要做一定的解释,不然读者可能会懵逼或者兴趣缺缺。

1.1什么是打包

打包本身有很多含义,这里的打包是指将 Python 源代码包括相关组件(包括一个Python解释器)打包成一个开箱即用的 .exe 文件或者包含着一个 .exe 文件的文件夹,说简单一点,就是把 Python 脚本变成一个双击就能使用的 .exe 可执行文件。

1.2为什么要打包

就如上一条才说的,“把 Python 脚本变成一个双击就能使用的 .exe 可执行文件”,这样做的好处是什么:

  • 跨设备,分发给多个设备,开箱即用;

  • 一键使用,用户不需要了解太多的信息;

  • 隐藏代码,无法直接看到你写的源代码,或许有用,但对于我没用;

  • 最最重要的一点就是,减少了库的安装,下载好的第三方库都被打包了进去,不用换一个环境发现缺少各种库的支持而不能运行;

  • ...

1.3针对 ArcPy 的半打包

打包的效果当然是非常的好的,但是,ArcPy 是随着 ArcGIS 安装而安装的,ArcGIS 是商业软件,ArcPy 也不是开源的,他是封闭的,所以是不能完全将 ArcPy 打包进一个可执行文件的,不过退而求其次,实现半打包也是可以的。

既然是半打包,那么相应的好处也是不能全兼的,这里详细说明,也适当的降低你的期望值。

  • 有这样两个可选的打包选项,第一个是打包的时候完全打包成一个可执行文件,这样比较方便,第二种呢是变成一个文件夹,其中有一些编码后的系统执行文件和一个可执行文件(你电脑中安装的程序几乎都是这样的),这样的好处是速度快点。对于半打包,只能选择后者

  • 打包好的可执行文件只能在安装了 ArcGIS(desktop版) 的电脑上运行。这一点几乎没有影响,因为公司的电脑基本上都有装 ArcGIS 的吧

除此之外,打包的优点都是继承的。

如何打包

这厉害的东西肯定有前人大神尝试过啦,最早的文章可以追溯到 ESRI 的博客《Using Py2exe with Arcpy- It can be done easily!》,然后就是国内 GIS 知乎的这篇文章《如何使用py2exe打包arcpy脚本》,后者在前者的基础上做了一些补充。

主要内容可以分为两部分,第一部分是常规的打包设置教程,使用 py2exe 程序对 Python 源代码进行打包,第二部分就是如何将 ArcPy 引入,最终实现 ArcPy 的半打包。

  • Using Py2exe with Arcpy- It can be done easily! https://community./t5/python-questions/using-py2exe-with-arcpy-it-can-be-done-easily/td-p/360520

  • 如何使用py2exe打包arcpy脚本?http://zhihu./article/2600

2.1 第一步 使用 py2exe 打包

py2exe 其实也是一个 python 库,不过早已停止更新,但是对付 Python2 还是绰绰有余的,py2exe 有一键安装的程序,非常方便。

打包至少需要两个文件,其中一个是新创建的 setup 文件(名称:mysetup.py),其中包含了各种打包参数;另一个是实际执行代码的主文件(名称:Gispot.py)。

mysetup.py 文件:

from distutils.core import setup
import py2exe
options = {"py2exe": {"excludes": ["arcpy"]}}
setup(
    windows=[{'script':'Gispot.py'}], # ▶注释一◀
    options=options
)

由于 ArcPy 是需要 ArcGIS 证书的站点包,无法完全将其打包进程序,所以这里使用 "excludes": ["arcpy"] 显式的将 ArcPy 拉入打包的“黑名单”,后面使用其他操作单独引入。

▶注释一◀:windows 可替换为 console,分别表示打包后的程序是独立窗口还是带一个终端界面。

Gispot.py 文件新增必要的打包代码:

import os
import sys
from site import addsitedir
interpreter = sys.executable
sitepkg = os.path.dirname(interpreter) + "\site-packages"
addsitedir(sitepkg)

sys.executable 可获取 Python 解释器的位置,然后传给打包程序。

  • py2exe 安装包下载地址:https:///projects/py2exe/files/py2exe/0.6.9/py2exe-0.6.9.win32-py2.7.exe/download

2.2 第二步 打包

两个文件放在同一文件夹下,运行 cmd 命令行,或者把命令行复制到 txt 中,然后修改后缀为 bat,直接运行也行:

python mysetup.py py2exe
Note:Python路径需要添加进环境变量。

打包后的成果一般位于 dist 文件夹中,其目录结构一般如下,展示的结构应该比你的复杂,因为自己在使用时添加了很多其他设置。

初步打包

2.3 第二步 外部引入 ArcPy

在上面展示的截图中,有一个 site-package 文件夹,这个需要你手动创建,熟悉 py2exe 的话也可以直接在 mysetup.py 文件中写入创建的操作。

然后在 site-package 文件夹中添加一个 .path 后缀的文本文件,在这个文本中添加上 ArcPy 以及相关的地址:

C:\Program Files (x86)\ArcGIS\Desktop10.3\bin
C:\Program Files (x86)\ArcGIS\Desktop10.3\ArcPy
C:\Program Files (x86)\ArcGIS\Desktop10.3\arcpy
C:\Program Files (x86)\ArcGIS\Desktop10.3\ArcToolBox\Scripts
C:\Python27\ArcGIS10.3\Lib
C:\Python27\ArcGIS10.3\Lib\site-packages

添加地址后,运行 exe 文件,程序就可以使用 ArcPy 相关的组件了。

于是乎,这样就可以在运行封闭的 .exe 文件时,引入 ArcPy,这就是所说的半打包,也是为什么只能运行在安装了 ArcGIS 的电脑的原因。

好的,到这里为止,就是我对前辈两篇文章的总结,但是实际使用的时候,问题很多。下面来看看解决方法。

引入方法的补充

令人苦恼的是,在引入 .path 后缀文件后,运行 .exe 可执行文件,依然会报找不到 arcpy 库的错误(ArcGIS10.3)。

如何解决这个问题呢?

既然我们知道 .path 文件会被系统读取,那我直接在这个文件中写上 import arcpy,这样行不行呢?

诶,这样还真行!

C:\Program Files (x86)\ArcGIS\Desktop10.3\bin
C:\Program Files (x86)\ArcGIS\Desktop10.3\ArcPy
C:\Program Files (x86)\ArcGIS\Desktop10.3\arcpy
C:\Program Files (x86)\ArcGIS\Desktop10.3\ArcToolBox\Scripts
C:\Python27\ArcGIS10.3\Lib
C:\Python27\ArcGIS10.3\Lib\site-packages
print "<<hello world>>"
import arcpy
print type(arcpy)

在我也不知道发生了什么,为什么会这样的情况下,我解决了几乎困扰了我一年的问题,简直亦可赛艇!

其他问题

读者朋友遇到的问题可能包括但不局限于以下我提到的问题,没有它做不到,只有你想不到,包括各种奇葩问题和错~

4.1 XML问题

除了找不到 arcpy 库的问题外,还可能有出现 xml 的问题,直接在 Gispot.py 中写上from xml.etree.ElementTree import ElementTree ,显式的导入该模块。

Gispot.py:

import os
import sys
from site import addsitedir
#<<<<<<<<<<<<<<<
from xml.etree.ElementTree import ElementTree
#<<<<<<<<<<<<<<<
interpreter = sys.executable
sitepkg = os.path.dirname(interpreter) + "\site-packages"
addsitedir(sitepkg)

4.2 matplotlib问题

报错说 Could not find the matplotlib data files。

也是手动导入 matplotlib,不过是写在 mysetup.py 文件中。

mysetup.py:

from distutils.core import setup
import py2exe
options = {"py2exe": {"excludes": ["arcpy"]}}
#<<<<<<<<<<<<<<<
import matplotlib
setup(data_files=matplotlib.get_py2exe_datafiles(),)
#<<<<<<<<<<<<<<<
setup(
    windows=[{'script':'Gispot.py'}],
    options=options
)

4.2 多进程问题

执行代码的主文件如果涉及多进程的话,打包后的程序也会执行失败,需要的主要文件,也就是这里的 Gispot.py 文件中添加 freeze_support() 方法以支持多进程打包为可执行文件。

Gispot.py:

...
if __name__ == '__main__':
    
    multiprocessing.freeze_support() # 支持多进程打包为可执行文件
    ...

总结

整个内容分为三部分,

第一部分:

  • 打包需要两个文件,以后是代码的主运行文件,另一个是纯粹为打包服务的参数配置文件;

  • 打包时应提前剔除掉 ArcPy 库;

  • 在终端(CMD)使用 python mysetup.py py2exe 命令执行打包;

  • 添加 .path 文件实现外部引入 arcpy。

第二部分:

  • 在 .path 文件中添加 import arcpy 实现库的导入,解决了程序找不到 arcpy 库的问题。

第三部分:

  • XML 相关错误的解决;

  • matplotlib 相关错误的解决;

  • 多进程打包的注意事项。

关于如何打包的问题这里基本就解决啦,在对 .path 文件做完善后,个人使用在10.2、 10.3、10.5 版本的 ArcGIS 上都是可以打包并成功运行的。

将打包后的程序放到其他装有 ArcGIS 的电脑上,也是可以运行的,甚至在 win7 版本的电脑上也可以运行。

如有错误的地方,欢迎指正,我只是一个小菜鸟~

可能遇到的错误也不止这几个,欢迎来互相伤害。

荟GIS精粹,关注公众号:GIS荟
如果对你有用,希望动动小手帮忙转发或点赞,求求你啦~

本系列专辑:

《ArcPy教程指南2021》——从0开始,从实际应用出发,带大家熟悉掌握 ArcPy。(持续更新中!)

都从2021年初写到2022年初了,应该是最后一节了吧 :D 求点赞~

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多