将python代码打包成一个app/exe

时间:2021-03-09 09:30:52

前言

  打包的代码通常都需要写一个简单的界面,一般用 PyQt 来写。用 PyQt 写界面的方法请戳这里:PyQt5的安装及基本配置    PyQt5教程

  python提供了几个用来打包的模块,主要有 py2app、py2exe、pyinstaller,其中第一个是用来打包来给 mac 用的,后两者是针对于 windows 系统。

关于 py2exe 和 pyinstaller 两者的比较:

  对于 pyinstaller 和 py2exe 两种把 Python 文件打包成 exe 可执行文件的方法,都有各自的优缺点。但是最终目的都是为了在没有 Python 环境下的普通  Windows 系统的电脑中可直接运行。py2exe 的使用方法基本和 py2app 一样,但是本人操作时发现在 mac 中无法用 py2exe 打包成 exe,但是可以用 pyinstaller 打包成 exe,没有尝试过是否可以在 windows 环境下用 py2app 打包成 app。pyinstaller (-F指令下)生成的 exe 文件,集成了所需要的所有资源(所以 exe 文件 相对较大),可直接拷贝到其他电脑中使用。对于 py2exe 来说,限制就比较多了,它所需要用到的外部资源都在 dist 目录下,想要在其他电脑中使用就必须把整个 dist 文件夹都拷贝过去。而且经测试在 64 位机器生成的 exe 无法在 32 位机器上打开使用。

  

py2app打包

注:py2app 方法已在 Mac 环境下测试无误,windows 环境操作时如果遇到问题请自行Google 

一、安装py2app

sudo pip install py2app

二、进入要打包的文件所在的文件夹

cd 。。。。。。。。

三、生成setup.py文件,该文件用于写打包所需要的依赖

py2applet   --make-setup  xxx.py  # xxx.py为项目的启动文件,之后生成的xxx文件就是双击执行的app文件

执行以后目录中会生成 setup.py 文件,用于写入依赖的库。

四、在 setup.py 文件中手动输入需要的依赖

  如果项目很简单,没有导入第三方库和自建模块,可以忽略此步骤。

  下面是setup.py文件的一个例子,手动输入的部分就是在 DATA_FILES 空列表里加自建模块的名字,在 OPTIONS 字典的 includes 对应的空列表中加第三方模块的名字

# python自带的库无需输入,第三方库和自己引入的自写模块需要输入
"""
This is a setup.py script generated by py2applet Usage:
python setup.py py2app
""" from setuptools import setup APP = ['start.py']
#自写模块放在DATA_FILES列表中
DATA_FILES = ['xxx1.py','xxx2.py','xxx3.py']
# 第三方库放在OPTIONS下的includes对应的列表中
OPTIONS = { 'includes': ['sip', 'PyQt5.QtCore', 'PyQt5.QtWidgets'],} setup(
app=APP,
data_files=DATA_FILES,
options={'py2app': OPTIONS},
setup_requires=['py2app'],
)

示例setup.py

五、生成app

# 自己开发,打包速度快。(因为本机安装了依赖库,所以可以直接运行)
python setup.py py2app -A # 给其他没有 sdk 的电脑使用,包括 lib 库。(没有安装 sdk 的电脑使用,需要去掉 -A,将把所有的依赖全部打包。)
python setup.py py2app 

  之后会生成 build 和 dist 两个文件夹,启动文件在 dist 下,双击就可以执行。

注:如果发现有问题,在重新进行上述步骤前最好先删除 build 和 dist 两个文件夹

rm -rf build dist

py2exe

  首先声明,py2exe 在高版本的 python 环境下可能会出现不支持的情况,我在打包的时候只支持到 python3.4,不清楚目前支持到哪个 python 版本。

注:本人在 win10 下用 py2exe 打包的含有 PyQt5 写界面的程序无法正常运行,遇到的问题很多,如果程序中用到了 PyQt5,推荐选用 pyinstaller 打包

一、安装py2exe

pip install py2exe

二、进入项目目录

cd xxxxxxxxx

三、在项目根目录中自行创建setup.py文件

  该文件的作用与 py2app 的 setup.py 文件一样,只不过需要自己手动创建,区别在于你可以任意命名该文件(如 woshinibaba.py)

四、在 setup.py(woshinibaba.py) 文件中写入需要的依赖

文件中基本格式为

# -*- coding: utf-8 -*-

from distutils.core import setup
import py2exe setup(
# console和windows分别代表控制台和图形界面,按需求选择
#console = [{"script" : 'comtrade.py'}],
windows = [{"script":"comtrade.py", "icon_resources": [(1, "logo.ico")]} ],
name = 'comtrade',# 生成的exe文件名
version = '1.0',
options={}, # 括号内填入的为项目所需的依赖库和会造成报错的文件
data_files={})# 括号内输入的为项目所需的依赖文件
# version ,description,name不是必须要写的。

其他参数:

  • dist_dir           打包生成的文件放在 dist 下,可设置存放目录(一般没有特殊要求,可以不需修改。可使用相对路径)
  • Compressed    默认为 0,1 为指定压缩文件(library.zip)的行为;0 为不压缩。
  • Zipfiles           配置共享压缩文件的生成目录和文件名,默认是在目录 dist 下生成一个  “library.zip” 文件,打包了 .exe 文件运行需要的 .pyd  和 .dll 文件(不包含配置文件等)。
  • Optimize         打包优化,合法值是字符串('','O','OO')或者整型数字 (0, 1, or 2)。
    • 为 0 时:不进行优化,压缩包大小较大,打包的编译文件为 .pyc;
    • 为 1 时:进行少量优化,压缩包大小略小,打包的编译文件为 .pyo;
    • 为 2 时:优化级别最高,压缩包大小也明显变小,打包的编译文件为 .pyo。
  • Bundle_files     打包绑定,64位不支持此属性。
    • 为 0 时:pyd 和 dll 文件不会被打包到 exe 文件中;
    • 为 1 时:pyd 和 dll 文件会被打包到 exe 文件中,且不能从文件系统中加载 python 模块;
    • 为 2 时:pyd 和 dll 文件会被打包到 exe 文件中,但是可以从文件系统中加载 python 模块。
    • 注:
      • .py:编写的源文件。
      • .pyc:编译过的二进制代码文件。如果导入一个模块,python 将创建一个 *.pyc 文件,文件内为二进制码,这样可以在再次导入时更容易(更快)。
      • .pyo:当优化等级 (-O) 开启时生成的 *.pyc 文件。
      • .pyd:相当于一个 windows dll 文件。实际上 .pyd 文件就是 dll 文件,只是略有不同。
  • Date_files       文件可执行文件所需数据。在 python27 中,需要的 MSVCP90.dll 不能单独发布,必须确保 py2exe 复制所有的三个 dll 文件和 manifest 文件到工程目录 dist 下,并且放在一个名为 'Microsoft.VC90.CRT' 的子目录下。
    • 参考做法为:
      from glob import glob  
      
      data_files  = [
      ("Microsoft.VC90.CRT",
      glob(r'C:\Program Files\Microsoft Visual Studio
      freeze_support9.0\VC\redist\x86\Microsoft.VC90.CRT\*.*'))
      ]
  • ascii               
    • 为 0 时:不包含编码和解码器;
    • 为 1 时则反之。
    • 假设出现 QPixmap::scaled: Pixmap is a null pixmap 问题,这是由于 PyQt 和 qt 都是默认的 png 格式的图片,打包后,会找不到 jpg 格式的图片,所以在打包过程中需要把 PyQt4 文件中的imageformats 文件夹下的 dll 文件导入。这是 jpg 格式的图片需要的插件。
  • 类标识符无属性,产生的CLSID无属性。

typelibs

列表:需要包含的gen_py产生的typelibs

  • 多进程打包遇到的程序不正常执行问题,需要在多进程之前调用 freeze_support() 函数。经试验,最好在函数开始执行的时候,首先调用此函数。

具体例子:

# -*- coding: utf-8 -*-

# 必须写的倒入模块
from distutils.core import setup
import py2exe # 可以不用写的部分
"""
#We need to import the glob module to search for all files.
import glob
import sys
#this allows to run it with a simple double click.
sys.argv.append('py2exe')
""" # 项目中需要用到的第三方库写入includes所对应的列表中
# 项目中用不到的会造成报错的文件放在excludes所对应的列表中,若报错的是dll文件,放入dll_excludes所对应的列表中
# 下面是示例:
opts= {
'py2exe':{ "includes" : [ "sip", "matplotlib.backends", "matplotlib.backends.backend_tkagg",
"matplotlib.figure","numpy", "matplotlib.pyplot", "pylab", "six",
"matplotlib.backend_bases", 'scipy.special._ufuncs_cxx',
"scipy.integrate","scipy.integrate.quadpack","scipy.sparse.csgraph._validation"],
"excludes" : ['_gtkagg', '_tkagg', '_agg2', '_cairo', '_cocoaagg',
'_fltkagg','_gtk', '_gtkcairo'], "dll_excludes":['libgdk-win32-2.0-0.dll','libgobject-2.0-0.dll',"MSVCP90.dll",]
}
} #项目中需要用到的外部文件依赖放入列表中,格式为[(),(),()]
# 元祖中第一个元素是打包时要创建的文件夹名,如果要放在exe文件的同目录下就用"",第二个元素是该依赖文件的路径
data_files= [(r'mpl-data',glob.glob(r'C:\Anaconda3\Lib\site-packages\matplotlib\mpl-data\*.*')),
#Because matplotlibrc does not have an extension, glob does not findit (at least I think that's why)
#So add it manually here:
(r'mpl-data',[r'C:\Anaconda3\Lib\site-packages\matplotlib\mpl-data\matplotlibrc']),
(r'mpl-data\images',glob.glob(r'C:\Anaconda3\Lib\site-packages\matplotlib\mpl-data\images\*.*')),
(r'mpl-data\stylelib',glob.glob(r'C:\Anaconda3\Lib\site-packages\matplotlib\mpl-data\stylelib\*.*')),
(r'mpl-data\fonts',glob.glob(r'C:\Anaconda3\Lib\site-packages\matplotlib\mpl-data\fonts\*.*')),
("",[r"C:\Anaconda3\Lib\site-packages\PyQt5\libEGL.dll"]),
("platforms",[r"C:\Anaconda3\Lib\site-packages\PyQt5\plugins\platforms\qwindows.dll"])] # 将上述参数传入setup中,console和windows分别代表控制台和图形界面,按需求选择
setup(
#console = [{"script" : 'comtrade.py'}],
windows = [{"script":"comtrade.py", "icon_resources": [(1, "logo.ico")]} ],
name = 'comtrade',
version = '1.0',
options=opts, data_files=data_files)

setup.py(woshinibaba.py)

五、生成exe 

python setup.py app2exe

执行完毕后会生成build和dist文件夹,启动文件在dist文件夹下

py2exe报错解决

1. 执行打包命令时报错 Missing run-py3.5-win-amd64.exe

  • 原因:py2exe 最高只支持到 python3.4,如果你用的 3.5 或更高的版本就会出现这个问题
  • 解决方法:创建个虚拟环境安装 python3.4,然后 pip install 所有项目需要的第三方库后重新进行一边打包操作

2. 执行打包命令时报错 indexError: tuple index out of range

  • 原因:py2exe 最高只支持到 python3.4,如果用更高的版本就会出现这个问题
  • 解决方法:创建个虚拟环境安装 python3.4,然后 pip install 所有项目需要的第三方库后重新进行一边打包操作

3. 执行打包操作时报错 (忘了具体报错信息,意思时递归深度超过最大限制)

  • 原因:py2ex e最高只支持到 python3.4,如果你用的更高的版本就会出现这个问题
  • 解决方法:创建个虚拟环境安装 python3.4,然后 pip install 所有项目需要的第三方库后重新进行一边打包操作

4. 打包 ok,但双击可执行文件时报错 Failed to execute script xxx

  • 原因:去 log 文件中查看,会发现报错信息为 no module named xxx,意思为项目中缺少 xxx 模块
  • 解决方法:pip install ,如果你确定你已经安装了该模块,那就在 setup.py(woshinibaba.py)文件最上面 import 该模块

5. 打包 ok,但双击可执行文件时弹窗报错 This application failed to start because it could not find or load the Qt platform plugin "windows".

注:这是我遇到的一个最大的问题,问题原因和 PyQt5 有关目前尚未找到解决方案,然后选用了 pyinstaller

  • 疑似原因一:python3.4 不支持 PyQt5
  • 本人理解:python3.4 环境下用 pip install PyQt5,报错说找不到该模块,但是可以运行 pip install pyqt,而 pyqt 指得是 PyQt4,两者是不一样的。在 pycharm 中将其升级为 PyQt5,惊奇的发现我的python 环境变成 python3.7了?!在升级 pyqt 的同时将我的 python 都升级了?但是 py2exe 不支持 python3.7 啊,WTF?!最后本人不了了之选择了pyinstaller
  • 疑似原因二:没有将 PyQt5 写入环境变量
  • 网上提供的解决方法一:将 QT 的 bin 目录下的 \platforms\qwindows.dll 拷贝至 exe 所在目录,注意保留 \platforms 子目录
  • 网上提供的解决方法二:在 data_files 参数中加入两个元祖,元祖中写入(该方法与上面的方法一个作用,他会在你执行打包命令时自动将将 QT 的 bin 目录下的 \platforms\qwindows.dll 拷贝至 exe 所在目录)
# 注:路径为你的python的PyQt5的路径
data_files=[("",
[r"F:\Python\python3\Lib\site-packages\PyQt5\libEGL.dll"]),
("platforms",
[r"F:\Python\python3\Lib\site-packages\PyQt5\plugins\platforms\qwindows.dll"])]
  • 网上提供的解决方法三:改变系统变量(变量值为你的 python 所在的目录下的 PyQt5 的目录)

                    将python代码打包成一个app/exe

  

pyinstaller

  首先要声明,pyinstaller 在高版本的 python 环境下可能会出现不支持的情况,我在打包的时候只支持到 python3.5,不清楚目前支持到哪个 python 版本。如果你的 python 已是3.5以上的版本,建议创建一个虚拟环境后安装 python3.5,再自行安装上程序所依赖的库比如 requests 等等,在新环境中进行打包。

注:pyinstaller 方法已在 win10、win8 和 Mac环境下测试无误,但打包程序本身会因为你的程序的不同而需要有些许改动,文章末尾会有一些我遇到过的报错的解决方法,出现问题可自行Google

一、安装pyinstaller

pip install pyinstaller

二、切换到工作目录

cd xxxxxxxxxxx

三、打包命令

  与上面两个不同的是,pyinstaller 不需要自己写 setup.py 文件,只需要在工作目录中输入打包命令即可。最后会生成 build 和 dist 文件夹,启动文件在 dist 文件夹下。

命令格式:

pyinstaller [项目启动文件]

其他参数(按需求选择):

  • -F   表示在 dist 文件夹下只生成单个可执行文件(内部包含所有依赖),不加默认会在 dist 生成一大堆依赖文件+可执行文件。
  • -D   与 -F 相反用法
  • -W  表示去掉控制台窗口,如果你的程序是有界面的,可以不写这个参数。但是测试情况下建议先加上这个参数,因为如果打包不成功,运行时报错信息会在控制台上输出,没有控制台就看不到报错信息。
  • -c   表示去掉窗框,使用控制台
  • -p    表示自己定义需要加载的类路径,项目中包含多个自建模块的时候需要加上 -p aaa.py -p bbb.py -p ccc.py
  • -i     表示可执行文件的图标,后面跟图标的路径
  • --hidden-import  后面跟模块名如 queue,用于告诉打包程序某个模块我用不着你不用打包进去

  打包完毕后在 dist 文件夹下双击项目启动文件就可以了

pyinstaller报错解决

1.执行打包命令时报错  IndexError: tuple index out of range

  • 原因:官网目前的版本是 3.2.1 只支持到 python3.5 ,高版本的 python 尚不支持,
  • 解决方法:网上有大神提供了完善版的代码——官网源码里有 https://github.com/pyinstaller/pyinstaller 替换你 python 目录下的 \Lib\site-packages\PyInstaller 即可 这样就支持python3.6了 不过是开发版,可能还不完善。

  作者建议最好还是用虚拟环境下的 python3.5 进行打包。


2.执行打包命令时报错 ImportError: No module named 'queue'

  • 原因:尚不清楚
  • 解决方法:如果该模块你用不到,可以在执行打包命令时用 --hidden-import 不打包进去。如果程序中需要该模块,在主文件最上面写上 improt queue

3.打包命令执行成功,但双击可执行程序弹出报错窗口failed to excute script xxx

  • 原因:打包时内部缺少了某个依赖,这时需要看看控制台打印了什么报错信息,打包时加了 -w 参数的请再打包一次记得去掉 -w
  • 现象:基本都是在控制台上发现报错 No module named 'xxxxx',如 No module named 'queue' 或者 ModuleNotFoundError: No module named 'PyQt5.sip'
  • 解决方法:同2,如果该模块你用不到,可以在执行打包命令时用 --hidden-import 不打包进去。如果程序中需要该模块,在主文件最上面写上 improt xxxxx。如 import queue 或 import PyQt5.sip

将python代码打包成一个app/exe的更多相关文章

  1. windows环境下把Python代码打包成独立执行的exe

    windows环境下把Python代码打包成独立执行的exe可执行文件   有时候因为出差,突然急需处理一批数据.虽然写好的脚本存储在云端随用随取,然而编译的环境还需要重新搭建,模块也需要重新装载,从 ...

  2. 用pyinstaller把python代码打包成exe可执行文件

    优点: 1. pyinstaller 是跨平台的可以用在linux和windows系统上 2. 操作非常简单,几个命令就搞定了,这个比py2exe容易用多了 缺点: 1. 打包后的体积过大,因为要带p ...

  3. windows环境下把Python代码打包成独立执行的exe可执行文件

    有时候因为出差,突然急需处理一批数据.虽然写好的脚本存储在云端随用随取,然而编译的环境还需要重新搭建,模块也需要重新装载,从头到尾这么一遍下来,也是要花费可观的时间成本的. 有没有什么办法,可以让.p ...

  4. Python代码打包成exe可执行程序

    首先,打包成exe可执行程序是针对windows平台来说的. 目前比较主流的打包工具就是pyinstaller. 参考:Using PyInstaller 首先安装pyinstaller: pip i ...

  5. 用PyInstaller把Python代码打包成单个独立的exe可执行文件

    之前就想要把自己的BlogsToWordpress打开成exe了.一直没去弄. 又看到有人提到python打开成exe的问题. 所以打算现在就去试试. 注:此处之所有选用BlogsToWordpres ...

  6. python代码打包成exe文件

    1.准备工作 1.安装pywin32.pyinstaller 2.准备好ico文件 找一个png格式的图片,使用png2ico脚本生成包含以下6个尺寸的ico文件:128×128 64×64 48×4 ...

  7. win7下用PyInstaller把Python代码打包成exe文件

    2013-11-05 22:02:14|   1.安装 使用PyInstaller需要安装PyWin32. 下载与Python对应的PyInstaller版本,解压后就算安装好了. 例如,安装了PyI ...

  8. Python 程序打包成 exe 可执行文件

    Python 程序打包工具 Python 是一个脚本语言,被解释器解释执行.它的发布方式: .py 文件:对于开源项目或者源码没那么重要的,直接提供源码,需要使用者自行安装 Python 并且安装依赖 ...

  9. 将 Python 程序打包成 .exe 文件

    1.简介 做了一个excel的风控模板,里面含有宏,我用python的第三方xlwings部署到linux后发现,linux环境并不支持xlwings. Python 程序都是脚本的方式,一般是在解析 ...

随机推荐

  1. UIImage 和 iOS 图片压缩UIImage / UIImageVIew

    UIImageView 制作气泡 stretchableImageWithLeftCapWidth http://blog.csdn.net/justinjing0612/article/detail ...

  2. ldconfig及 LD_LIBRARY_PATH

    dconfig及 LD_LIBRARY_PATH 1. 往/lib和/usr/lib里面加东西,是不用修改/etc/ld.so.conf的,但是完了之后要调一下ldconfig,不然这个library ...

  3. 关于 cookie 使用中遇到的问题

    前段时间在一个项目中涉及到cookie的存取,于是打算封装一个 cookie 的CRUD .按理来说,这本身是一个很简单的问题,不注意的话简单的问题也有大坑. /** * Set or get coo ...

  4. Android OpenGL ES 开发(三): OpenGL ES 定义形状

    在上篇文章,我们能够配置好基本的Android OpenGL 使用的环境.但是如果我们不了解OpenGL ES如何定义图像的一些基本知识就使用OpenGL ES进行绘图还是有点棘手的.所以能够在Ope ...

  5. 久未更 ~ 三之 —— CardView简单记录

    > > > > > 久未更 系列一:CardView 点击涟漪效果实现 //在 cardview 中 实现点击涟漪效果 android:clickable="t ...

  6. 并发容器和框架之ConcurrentHashMap

    了解HashMap的人都知道HashMap是线程不安全的(多线程下的put方法达到一定大小,引发rehash,导致闭链,最终占满CPU),同时线程安全的HashTable效率又令人望而却步(每个方法都 ...

  7. BZOJ_2795_[Poi2012]A Horrible Poem_hash+暴力

    Description 给出一个由小写英文字母组成的字符串S,再给出q个询问,要求回答S某个子串的最短循环节. 如果字符串B是字符串A的循环节,那么A可以由B重复若干次得到. Input 第一行一个正 ...

  8. 算法与数据结构(七) AOV网的拓扑排序(Swift版)

    今天博客的内容依然与图有关,今天博客的主题是关于拓扑排序的.拓扑排序是基于AOV网的,关于AOV网的概念,我想引用下方这句话来介绍: AOV网:在现代化管理中,人们常用有向图来描述和分析一项工程的计划 ...

  9. python安装pandas模块

    直接安装时报错了 localhost:~ ligaijiang$ pip3 install pandas Collecting pandas Downloading https://files.pyt ...

  10. 详解 java socket

    一,网络编程中两个主要的问题 一个是如何准确的定位网络上一台或多台主机,另一个就是找到主机后如何可靠高效的进行数据传输. 在TCP/IP协议中IP层主要负责网络主机的定位,数据传输的路由,由IP地址可 ...