最近使用PyInstaller对我的Python程序打包。
环境:Python 3.4.3 32 bit+PyQt 4.8.7 for py3.4 32 bit + Pandas + Multiprocess
打包中有几个坑,一定要越过去,不然会死的很惨。
1:支持multiprocess
当你使用多进程的模块时,一定要在 __main__方法下面紧跟着加上如下代码:
multiprocessing.freeze_support()
这种方式只针对打包中的"--onedir"模式,如果是"--onefile",那就要采用另外方法了,参考:Recipe Multiprocessing
2:支持Pandas库
Pandas是用C写的一套python库,所以,在支持C库打包的时候,必须采用pyinstaller的spec方式打包,把打包的命令各种写到 spec 文件里。为了支持pandas,必须这么干:
先放出参考链接:pyinstaller-and-pandas
在spec文件中,在
a = Analysis(...)这下面,紧接着加入下面代码:
def get_pandas_path(): import pandas pandas_path = pandas.__path__[0] return pandas_path dict_tree = Tree(get_pandas_path(), prefix='pandas', excludes=["*.pyc"]) a.datas += dict_tree a.binaries = filter(lambda x: 'pandas' not in x[0], a.binaries)
这样子就支持pandas了。
3:打包好的程序,运行始终报错:“ImportError: DLL load failed:找不到指定模块”
首先在代码中解决该问题,我们追加系统path到我们当前的目录,这段代码建议放在main方法开头,不过如果支持multiprocess的话,那就放在支持multiprocess代码下:
frozen = 'not' if getattr(sys, 'frozen', False): # we are running in a bundle frozen = 'ever so' bundle_dir = sys._MEIPASS else: # we are running in a normal Python environment bundle_dir = os.path.dirname(os.path.abspath(__file__)) win32api.SetDllDirectory(bundle_dir) sys.path.append(bundle_dir)
再次打包,如果依然报错,那么,建议安装
微软最全常用运行库合集下载(vcredist x64及vcredist x86)
只要把微软常用运行库安装好了,缺失DLL的问题就迎刃而解了。
最后,放出我的打包spec文件
ClientMain.spec:
# -*- mode: python -*- block_cipher = None def get_pandas_path(): import pandas pandas_path = pandas.__path__[0] return pandas_path added_files = [('D:\\Python34\\DLLs\\python3.dll', '.'),('*.dll', '.'),('img', 'img'),('image', 'image'),('config', 'config')] a = Analysis(['ClientMain.py'], pathex=['.', 'D:\\CTP\\PyCTP\\PyCTP_Client\\PyCTP_ClientCore'], binaries=[('PyCTP.pyd',''), ('thostmduserapi.dll',''), ('thosttraderapi.dll','')], datas=added_files, hiddenimports=[], hookspath=[], runtime_hooks=[], excludes=[], win_no_prefer_redirects=False, win_private_assemblies=False, cipher=block_cipher) dict_tree = Tree(get_pandas_path(), prefix='pandas', excludes=["*.pyc"]) a.datas += dict_tree a.binaries = filter(lambda x: 'pandas' not in x[0], a.binaries) pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) exe = EXE(pyz, a.scripts, exclude_binaries=True, name='ClientMain', debug=False, strip=False, upx=False, console=True , icon='img\\rocket.ico') coll = COLLECT(exe, a.binaries, a.zipfiles, a.datas, strip=False, upx=False, name='ClientMain')
打包执行命令:
pyinstaller --onedir --noupx ClientMain.spec
文章的脚注信息由WordPress的wp-posturl插件自动生成