Python之点到为止: 优美的打包你的代码(一)基础

2020年04月18日 6299点热度 1人点赞 0条评论

经过前几期文章, 想必你想要的功能都已经完成了. 那么如何打包呢?

为什么要打包

无外乎就是想让用户获得更好的体验, 不是所有用户都会去配置Python环境. 就算是你下面的用户都会配置环境, 也未必不会再环境上出错. 那么在这个部分去花时间处理是不值当的.

这是个漫长的过程, 打包简单优化难. 一个程序打包你说难么? 没有任何难度, 为何这么说?

理解打包

想一想你编写的Python脚本是如何运行的. python xx.py 对吧. 配置好环境变量后就这样执行, 那么没有添加环境变量如何运行?

c:\python3.6\python.exe xx.py
c:\python3.6\python.exe -m xx

那就直接把你自己的Python文件夹和代码压缩在一起直接用RAR弄个自解压程序, 设置好执行命令就好了啊. 还可以解压到临时文件夹运行完就删. 这就是非常简单的打包. 该有的都有, 缺点是什么? 文件大, 我这随手拿一个之前新建的虚拟环境就几百兆. 压缩后也是百兆级别, 你说我写个清理垃圾的小程序之不至于下一个几百兆的软件??? ??

相关模块

  • PyInstaller
  • cx-Freeze
  • Nuitka

用的最多的可能就是PyInstaller了. 今天这篇文章就不说一些百度上能搜到那些垃圾东西了, 之前在52破解也分享了一篇文章https://www.52pojie.cn/thread-1139585-1-1.html 就不赘述了. 还是按照惯例讲痛点或常用的东西.

打包代码来自之前文章分享: https://github.com/Virace/python-jgah/blob/master/Main/2153/tkinter.py

PyInstaller

pyinstaller -D xxxx.py

  • 想要单文件更小, 命令中添加 --upx-dir 后面加上upx程序所在的目录 https://github.com/upx/upx/releases/
  • 想要稍微加密你的代码, 命令中添加 --key 后面加上16位密钥可以自己随机生成一个. (需要安装PyCrypto)
  • 有些程序使用upx之后会无法运行(有自校验), 可以通过 添加 --upx-exclude 后面加上排除的exe文件名, 或者直接使用 --noupx 直接不使用用upx
  • GUI程序想要不显示控制台, 命令中添加 -w , 相反如果必须显示控制台则添加 -c : https://pyinstaller.readthedocs.io/en/stable/usage.html#windows-and-mac-os-x-specific-options
  • 需要一个图标, 命令中添加 -i 后面加上图标文件, 或者其他有图标的exe文件.
  • 需要默认已管理员权限运行, 命令中添加 --uac-admin
  • 给程序添加版本信息, 命令中添加 --version-file 后面接版本文件. 格式如下. 个人还是喜欢ResourceHacker去添加.
# UTF-8
#
# For more details about fixed file info 'ffi' see:
# http://msdn.microsoft.com/en-us/library/ms646997.aspx
VSVersionInfo(
  ffi=FixedFileInfo(
    # 文件版本信息为元组格式
    # 如果不需要着设置为0
    filevers=(10, 0, 18362, 1),
    prodvers=(10, 0, 18362, 1),
    # 文件标志掩码
    mask=0x3f,
    # 文件标志(是否包含调试版本,动态版本结构...)
    flags=0x0,
    # 文件指定的操作系统
    # 0x4 - NT 不需要修改
    OS=0x40004,
    # The general type of file.
    # 0x1 - the file is an application.
    fileType=0x2,
    # 文件类型, APP、DLL啥的
    subtype=0x0,
    # 创建时间戳
    date=(0, 0)
    ),
  kids=[
    StringFileInfo(
      [
      StringTable(
        u'040904B0',
        [StringStruct(u'CompanyName', u'Microsoft Corporation'), # 公司名
        StringStruct(u'FileDescription', u'DLL for TaskRT'), # 文件描述
        StringStruct(u'FileVersion', u'10.0.18362.1 (WinBuild.160101.0800)'), # 文件版本
        StringStruct(u'InternalName', u'TaskApis'), # 内部名称
        StringStruct(u'LegalCopyright', u'© Microsoft Corporation. All rights reserved.'), # 版权信息
        StringStruct(u'OriginalFilename', u'TaskApis.dll'), # 源文件名
        StringStruct(u'ProductName', u'Microsoft® Windows® Operating System'), # 产品名称
        StringStruct(u'ProductVersion', u'10.0.18362.1')]) # 产品版本
      ]), 
    VarFileInfo([VarStruct(u'Translation', [1033, 1200])]) # 语言信息
  ]
)

这可能是一些很好用但是很少用, 并且用的时候找不到(除文档)的参数. 如果有其他需要的可以一起讨论呦. ? 哦对了, 不推荐大家使用 -F 打包单文件会影响启动时间. 实在需要单文件可以使用rar自解压程序.

cx-Freeze

这个模块不管从名字还是从打包用脚本来说我个人对它好感度都很高. 但是默认命令打包优化效果并不好. 其特点就是打包可以使用脚本方式调用.

# https://github.com/anthony-tuininga/cx_Freeze/blob/master/cx_Freeze/samples/Tkinter/setup.py
import sys
from cx_Freeze import setup, Executable

base = None
if sys.platform == 'win32':
    base = 'Win32GUI'

executables = [
    Executable('SimpleTkApp.py', base=base)
]

setup(name='simple_Tkinter',
      version='0.1',
      description='Sample cx_Freeze Tkinter script',
      executables=executables
      )

我是比较喜欢这种的, 不需要什么bat啊, shell脚本来掺和. 这样整体化很强(强迫症). 但其更大的特点是打包为安装包, 支持不同系统打包安装文件, 例如: 打包exe利用msi、 打包rpm包、甚至mac下.app dmg捆绑包.

Nuitka

这个模块给我的感觉就像: 面前一群糙老爷们, 回头一看有个小姑娘. 立志于将Python转成C再编译成EXE. 哎这样你的Python代码安全性就上去了. 也就只能从汇编上看看"源代码".

关于他如何使用可以查看: https://www.52pojie.cn/thread-1139585-1-1.html

这个库的痛点就是, 环境配置. 嗯对环境配置, MSVC安装还是简单的, 但是不想用因为会添加一些MSVC的DLL, 卵用. 然而MinGW大家可以百度百度. = =对于网络差而且还在墙里的用户那是极其不友好的.

总结

其实PyInstaller比早些时间强的太多了, 最开始还动不动几十兆现在可以在十几兆之内. 除了单文件启动上有些慢外现在已经很不错了, 更何况字节码都可以加密了(安全性和Nuitka没法比).

那么我就点到为止了
Just give a hint.

相关链接:
Pyinstaller文档: https://pyinstaller.readthedocs.io/en/stable/usage.html
ex_Freeze文档: https://cx-freeze.readthedocs.io/en/latest/overview.html
Nuitka文档: https://www.nuitka.net/doc/user-manual.html

文章评论