【整理】PyInstaller针对包含Python3.4, PyQt, Pandas, Multiprocess的程序打包

最近使用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插件自动生成



|2|left
打赏

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: