zoukankan      html  css  js  c++  java
  • 利用pyinstaller将python脚本打包发布

      之前写了一个小工具,将excel配置表转换为json、xml、lua等配置文件。最近在学习egret,正好需要转换配置文件,刚好就用上了。然而当我想把工具拷到工作目录时,就发愁了。之前我为了方便扩展,把程序拆分得太细:

    xzc@xzc-HP-ProBook-4446s:~/Documents/code/github/py_exceltools$ ls -lh
    总用量 80K
    drwxrwxr-x 2 xzc xzc 4.0K  7月 27 23:03 bin
    drwxrwxr-x 2 xzc xzc 4.0K  7月 27 23:03 client
    -rw-rw-r-- 1 xzc xzc 7.7K  7月 27 23:03 decoder.py
    -rw-rw-r-- 1 xzc xzc  893  7月 27 23:03 error.py
    -rw-rw-r-- 1 xzc xzc  16K  7月 27 23:03 example.xlsx
    -rw-rw-r-- 1 xzc xzc  131  7月 27 23:03 lancher.bat
    -rw-rw-r-- 1 xzc xzc  127  7月 27 23:03 lancher.sh
    -rw-rw-r-- 1 xzc xzc 3.9K  7月 27 23:03 loader.py
    -rw-rw-r-- 1 xzc xzc  705  7月 27 23:03 loader.spec
    -rw-rw-r-- 1 xzc xzc 2.4K  7月 27 23:03 README.md
    drwxrwxr-x 2 xzc xzc 4.0K  7月 27 23:03 server
    -rw-rw-r-- 1 xzc xzc 4.0K  7月 27 23:03 writer_json.py
    -rw-rw-r-- 1 xzc xzc 7.2K  7月 27 23:03 writer_lua.py
    -rw-rw-r-- 1 xzc xzc 5.6K  7月 27 23:03 writer_xml.py

    如此多的文件,放到工作目录不太好组织,也容易与项目的源代码混在一起。毕竟我用的vs code分不清哪些才是工程内文件。何况以后还要给策划用,还得装python和openpyxl库,部署比较麻烦。于是想尝试一下把python脚本打包为一个exe文件。

      google了一下,常用的工具不外乎pyinstaller和py2exe。两者的功能都差不多,但是发现pyinstaller有一个参数 --onefile,即脚本都打包成单个可运行文件,这不正是我要的么。于是下载安装来尝试一下:

    py_exceltools$pip install pyinstaller
    py_exceltools$pyinstaller -F loader.py
    
    ...
    tuple index out of range

    安装过程很顺利,但是打包时却报了个错("tuple index out of range")。google一下"pyinstaller tuple index out of range",在github中发现是pyinstaller3.2.1不兼容python3.6.1。但是看看issue的回复,在dev版本是修复了。于是想试一下开发版本,不过看了一眼README,发现OS X、Linux、Win三个平台的CI都是failing:

    想想还是算了吧,免得折腾半天又不能用。直接把本机的python从3.6.1降为3.5,再从新安装pyinstaller,运行"pyinstaller -F loader.py"打包,一切顺利,在dist目录下生成了一个loader.exe。试运行下loader.exe,结果却是这样的:

    Traceback (most recent call last):
    File "loader.py", line 96, in <module>
    options.timeout,options.suffix,options.srv_writer,options.clt_writer )
    File "loader.py", line 25, in __init__
    self.srv_writer = importlib.import_module( "writer_" + srv_writer )
    File "importlib\__init__.py", line 126, in import_module
    File "<frozen importlib._bootstrap>", line 986, in _gcd_import
    File "<frozen importlib._bootstrap>", line 969, in _find_and_load
    File "<frozen importlib._bootstrap>", line 956, in _find_and_load_unlocked
    ImportError: No module named 'writer_lua'
    Failed to execute script loader
    请按任意键继续. . .

    缺失了模块writer_lua,这是我自己写的一个转换为Lua配置的模块。pyinstaller本来有分析脚本依赖的模块的,但是我这个程序是根据运行时传入的参数动态加载模块的,因为我并不能预先知道用户要把excel转换为什么类型的文件。全部加载所有模块,是一个解决方案,但不太合适,因为我本来的写法是:规定了模块的接口,新增模块时,不需要修改我原有的代码,会自动加载新模块。再次搜索了一下,居然没有找到相同的案例。阅读了下pyinstaller的手册(https://pythonhosted.org/PyInstaller/spec-files.html),发现可以用spec配置文件来打包各种数据的,比如程序的icon,甚至自定义的一些二进制文件。在http://pythonhosted.org/PyInstaller/when-things-go-wrong.html#listing-hidden-importshttp://pythonhosted.org/PyInstaller/hooks.html#understanding-pyinstaller-hooks中提到可以使用hiddenimports选项来导入隐藏的模块。

      查看了下pyinstaller打包的过程,运行"pyinstaller -F loader.py"时确实在当前目录下生成了一个loader.spec文件:

    # -*- mode: python -*-
    
    block_cipher = None
    
    
    a = Analysis(['loader.py'],
                 pathex=['E:\linux_share\github\py_exceltools'],
                 binaries=[],
                 datas=[],
                 hiddenimports=[],
                 hookspath=[],
                 runtime_hooks=[],
                 excludes=[],
                 win_no_prefer_redirects=False,
                 win_private_assemblies=False,
                 cipher=block_cipher)
    pyz = PYZ(a.pure, a.zipped_data,
                 cipher=block_cipher)
    exe = EXE(pyz,
              a.scripts,
              a.binaries,
              a.zipfiles,
              a.datas,
              name='loader',
              debug=False,
              strip=False,
              upx=True,
              console=True )

    在hiddenimports中加入自己动态加载的模块,变成hiddenimports=['writer_lua','writer_xml','writer_json'],重新打包。注意,重新打包时不要再运行"pyinstaller -F loader.py"了,因为这个指令会重新生成spec文件,把你修改的覆盖了。直接用"pyinstaller loader.spec"来打包。

      加入动态加载的模块后,整个exe有7M多,运行正常。但是在64bit系统打包出来的程序,是64bit的,不能在32bit下运行。整个工具放在github上:https://github.com/changnet/py_exceltools

  • 相关阅读:
    DSYMTools App Bug 分析工具
    Xcode dSYM 文件
    sqlserver数据库18456错误怎么解决?
    C#两个DataTable拷贝问题:该行已经属于另一个表的解决方法
    SNF微信公众号客户端演示-微信开发客户端能干什么
    sqlserver中创建链接服务器图解教程
    C#日期格式转换大全
    C#-MVC开发微信应用(8)--菜单管理的实现
    C#-MVC开发微信应用(7)--在管理系统中同步微信用户分组信息
    C#-MVC开发微信应用(6)--用户分组信息管理
  • 原文地址:https://www.cnblogs.com/coding-my-life/p/7248072.html
Copyright © 2011-2022 走看看