py打包成exe-PyInstaller

PyInstaller打包成exe

使用插件:
PyInstaller

安装

安装方式

pip install PyInstaller

问题

ImportError: 'module' object has no attribute 'check_specifier

如果出现上面的问题,先尝试更新:

pip install --upgrade setuptools

再执行安装指令

如果上述操作存在问题,使用 管理员 试试!

使用

文档:PyInstaller Manual

windows用法

windows下使用gb2312保存文件

echo off
rem 请把python:path/Scripts添加到系统路径
rem cxfreeze,pyinstaller都在这个路径下
rem !!!在windows下编写bat,路径使用[\],不要使用 [/]
rem py文件,不要带后缀[.py]

set py_file=test
rem 中间目录
set out_dir=.\dist
rem 自己的模块位置
set my_py_module_path=..\
rem 图标icon
set icon=test.ico

echo %cd%

rem warning: 在执行完毕会删除中间目录,同时会把exe拷贝到上层目录
rem 所以建议把中间目录就设置在工作目录下
rem 文档:https://pyinstaller.readthedocs.io/en/v3.5/
rem LEVEL may be one of TRACE, DEBUG, INFO, WARN, ERROR, CRITICAL (default: INFO).
pyinstaller -F -c --distpath=%out_dir% --workpath=%out_dir%\build --specpath=%out_dir%\build --path=%my_py_module_path% --name=%py_file%.exe -y --clean --log-level=WARN --icon=..\..\%icon% %py_file%.py

rem 复制到当前目录
copy /Y /B %out_dir%\%py_file%.exe .\
rem 删除目录
rd /Q /s %out_dir%

echo "finish!"

linux用法

#!/bin/sh

# py文件,不要带后缀[.py]
py_file=test
# 中间目录
out_dir=./dist
# 自己的模块位置
my_py_module_path=.
# 获取当前工作目录
cd=$(cd `dirname $0`; pwd)

echo $cd

pyinstaller -F -c --distpath=$out_dir --workpath=$out_dir/build --specpath=$out_dir/build --path=$my_py_module_path --name=$py_file.app -y --clean --log-level=WARN --add-data=$cd/"resource/gdb_show_details.cmd:resource" $py_file.py

cp -f $out_dir/$py_file.app ./
rm -rf $out_dir

echo "finish!"

上面的命令行是个人使用,放在这里仅供参考!
PyInstaller

命令解释参考文档!

最终成功生成exe

问题

上面的命令行能执行成功,但是有坑

files_copy.py和copy.ico在同一个目录,但是2个文件指定路径不一样

如果要使用同一目录: –icon=copy.ico files_copy.py

测试结果是去掉 –specpath 就好了

对比

名字安装难度使用难度单文件文件大小
cx_Freeze易-不支持python27.dll:2.34 MB安装时
cx_Freezeexe:1.17 MB
pyinstaller支持exe:4.20 MB命令行

技术点

–add-data

使用此命令的资源如何取出 ?


def pkg_res(filename):
    if hasattr(sys, '_MEIPASS'):
        base_path = sys._MEIPASS
    else:
        base_path = os.path.abspath('.')
    return os.path.join(base_path, filename)

def read_f():
    f_res = pkg_res("resource/gdb_show_details.cmd")
    with open(f_res, 'rt') as fr:
        print(fr.read())

进阶1

把 隐藏 或者 没有显示import的python代码 打进包内.

如运行时动态加载的python代码, 在用pyinstaller打包时,是不会打进去的. 解决这个问题的方式比较简单,也算是有些另类.

先用上面的命令行成功打出执行程序, 在打出执行程序后,在 dist 也可能是 build 目录下会生成一个 spec 文件.

下面贴一个spec文件(我的spec文件全名是main.exe.spec)内容示例:

# -*- mode: python ; coding: utf-8 -*-

block_cipher = None


a = Analysis(['main.py', 'package.py'],
             pathex=['', '.\\dist\\build'],
             binaries=[],
             datas=[],
             hiddenimports=[],
             hookspath=[],
             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='main.exe',
          debug=False,
          bootloader_ignore_signals=False,
          strip=False,
          upx=True,
          upx_exclude=[],
          runtime_tmpdir=None,
          console=True , icon='main.ico')

注意 可以要修改spec文件里的路径.

创建一个新的py文件叫package.py(名字没有要求,自己随意), 把隐式加载的py全部在这个文件里进行import, 这个文件只有import, 测试案例的内容如下:

# -*- mode: python ; coding: utf-8 -*-
# 此文件存在的意义是为了配合pyinstaller工具打包
# 并没有实际意义

from my.lib1.code import *
from my.lib1.instructions import *
from my.lib2.code import *
from my.lib2.instructions import *

我的py的入口代码文件是main.py, 在spec里找到['main.py'], 一眼看出这是个数组,在这个数组里添加package.py, 重新打包. 执行程序里就有隐式的py代码了.

进阶2

电脑里同时安装了py27, py38(py3+) , 环境(命令行)默认是py27, 怎么为py38安装pyinstaller?

进入到py38的安装目录, 执行命令行:

.\Scripts\pip.exe install pyinstaller

进阶3

电脑里同时安装了py27, py38(py3+) 怎么指定py版本进行打包.

参考下面bat文件内容:

echo off

set PYTHON=D:\Python38_32;D:\Python38_32\lib;\D:\Python38_32\DLLs;D:\Python38_32\libs;D:\Python38_32\Scripts
set path=%path%;%PYTHON%


D:\Python38_32\Scripts\pyinstaller main.exe.spec

rem py文件,不要带后缀[.py]
set py_file=main
rem 中间目录
set out_dir=.\dist


rem 复制到当前目录
copy /Y /B %out_dir%\%py_file%.exe .\

rem 删除目录
rd /Q /s %out_dir%
rd /Q /s .\build

echo "finish!"
pause
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值