最近需要打包一个python项目成exe文件,里面有3个文件夹,和1个共享文件夹,所以需要打包多个py文件,还需要包含共享文件夹中的py文件。总之就是要将不同文件夹下的多个py文件打包。
通过了解,这里选择使用pyinstaller库来打包。
pip install pyinstaller
有两个打包方式:
-
使用命令行方式
pyinstaller [主文件] -p [其他文件1] -p [其他文件2] --hidden-import [自建模块1] --hidden-import [自建模块2]
如果在py文件很多的情况下,这个方法并不好。
-
使用spec方式
-
打开终端进入项目路径下,输入
pyinstaller -F -c docx2xml.py(项目主文件)
。执行后,会在当前目录下生成两个文件夹(build和dist)和1个文件docx2xml.spec
。删除那两个文件夹,只保留docx2xml.spec
。做个说明,这里的
pyinstaller -F -c docx2xml.py(项目主文件)
可以写成pyinstaller -F -w docx2xml.py(项目主文件)
。只不过-c
的在执行打包后的exe文件时会带控制台,也就是DOS窗口,而-w
不带控制台。在第一次打包时,如果程序打包后有错误,用-c
的可以在执行打包后的exe文件时直观地看到程序报错信息。 -
根据自己的项目编辑该文件
# -*- mode: python ; coding: utf-8 -*- block_cipher = None #此项目中所有的py文件(要打包进去的所有py文件),和主程序不在同一个包中的py文件用绝对路径。 a = Analysis(['docx2xml.py','content.py','extract.py','head.py','image.py','processXml.py', 'D:/Desktop/PaperSystem-Python/lib/log.py', 'D:/Desktop/PaperSystem-Python/lib/misc.py', 'D:/Desktop/PaperSystem-Python/lib/procXml.py', 'D:/Desktop/PaperSystem-Python/lib/styleEnum.py', ], pathex=['D:/Desktop/PaperSystem-Python/doc2xml'], # 项目的绝对路径 binaries=[], datas=[], hiddenimports=[], hookspath=[], hooksconfig={}, runtime_hooks=[], excludes=[], win_no_prefer_redirects=False, win_private_assemblies=False, cipher=block_cipher, noarchive=False) pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) exe = EXE(pyz, a.scripts, a.binaries, a.zipfiles, a.datas, [], name='docx2xml', #打包程序的名字 debug=False, bootloader_ignore_signals=False, strip=False, upx=True, upx_exclude=[], runtime_tmpdir=None, # console=True表示,打包后的可执行文件双击运行时屏幕会出现一个cmd窗口,不影响原程序运行 console=True, disable_windowed_traceback=False, target_arch=None, codesign_identity=None, entitlements_file=None ) # 如果想要修改程序图标,使用在EXE()中加入 icon='xxxxx', 切记:绝对路径
-
打包
执行spec文件:
pyinstaller -F -c docx2xml.spec
运行结束后,会新增dist文件夹,exe文件就在里面。(该exe文件已将所有的py文件封装完了,可随处使用)。
打包后遇到的一些问题
1.至此,python程序确实是打包完成了,但是还是有可能在运行时发生一些错误。
比如我在运行时,突然报了个错误,是因为在
lib
包中的调用模块处有问题:因为
log.py
和procXml.py
在同一个包下,所以当时在引用时用了相对路径。但是在打包后,程序会有错误。(可能是失去了相对路径,找不到所需的模块)所以要使用完整的调用模块的语句。2.原本的py程序执行时的参数都是使用命令行参数来传参的。打包之后的传参方式其实也一样,只不过每次执行exe文件时都要手动输入:
如何执行:
在执行exe文件的语句后加个空格,然后直接输入所需命令行参数。
-
参考博文:https://www.cnblogs.com/ronyjay/p/12713078.html