python应用打包分发纪要

农夫山泉,喝起来有点甜;python应用,运行起来有点慢。但,除了慢,它就别无缺点了。

前言

只有打包,才方便分发,才能流传后世。故此,颇有研究必要。
PyQt + pyinstaller成为一些中小项目界面包装和软件分发的优良选择。多快好省,省去很多烦恼。
打包主要是收集依赖,其次是形成正确的目录结构,最后才是包装成平台需要的可执行程序。

打包工具:PyInstaller,nuitka,cx_Freeze,PyOxidizer,PyInstaller-Qt,PyInstaller-PySide,Py2exe
首选pyinstaller,此选nuitka。pyinstaller打包速度快,但nuitka打包后的程序运行更快,代码更难被破解。nuitka打包会遇到各种问题。

Python程序分发思考

  1. pyinstaller 打包, – 需要各平台单独打包。有反编译风险。
  2. 用 Cython 将 py 编译成 .pyd/.so ->在用 pyinstaller 进行打包 。 – 各平台单独打包分发、反编风险小
  3. pyarmor 是一个专业混淆代码库,也是编译成字节码然后用-> pyinstaller 打包分发 ---- 各平台单独打包分发、反编风最小
  4. Nuitka 直接使用 Clang 进行编译运行。

pyc文件: Python源代码import后,编译生成的字节码,类似于java的class文件。例如__pycache__ 目录用于存放pyc

PYD 文件是用Python 编写的动态链接库,可以在运行时由其他Python 代码运行。 它包含一个或多个Python 模块,便于代码重用,并为编写应用程序提供模块架构。pyd库可以被python调用,也可以被C或其它程序调用。ctypes.cdll.LoadLibrary()用于加载pyd文件。

Cython

cythonize可以将py文件编译成pyd。

pip install Cython
cythonize -i -3 --directive always_allow_keywords=true xxx.py

python中调用pyd:

import ctypes

# 加载 Pyd 文件
mylib = ctypes.cdll.LoadLibrary('mylib.pyd')

# 调用 Pyd 文件中的函数
result = mylib.add(1, 2)

# 打印结果
print(result)

pyinstaller

pyinstaller options script.spec

当通过spec文件来生成app文件的时候只有下面几个参数是有用的:

  • –upx-dir=
  • –distpath=
  • -noconfirm=
  • –ascii

nuitka

Nuitka提供了一个激进的解决方案。它将Python程序编译为C语言二进制文件——不是通过将CPython运行时与程序字节码打包,而是通过将Python指令翻译成C语言。其结果能够以压缩包的形式分发,也可以与其他第三方产品一起打包到安装程序中。Nuitka还试图保持与Python生态系统的最大兼容性,因此NumPy等第三方库可以可靠地工作。Nuitka还尽可能地对编译后的Python程序进行性能改进,但同样不会牺牲整体兼容性。

ccache

ccache(“compiler cache”的缩写)是一个编译器缓存,该工具会高速缓存编译生成的信息,并在编译的特定部分使用高速缓存的信息, 比如头文件,这样就节省了通常使用 cpp 解析这些信息所需要的时间。如果某头文件中包含对其他头文件的引用,ccache会用那个文件的 cpp-parsed版本来取代include声明,不是真正去读取、理解并解释其内容,ccache 只是将最终的文本拷贝到文件中,使得它可以立即被编译。ccache是以空间换取速度,ccache非常适合经常make clean(或删除out目录)后重新编译的情况。

nuitka打包原理

nuitka打包过程,就是一个将引用的库打包成pyd的过程。根据py文件中from、import遍历相应模块文件打包到打包程序中,一旦遇到pyd,则不再递归查找下一层模块py文件。

nuitka主要参数

  • –nofollow-imports, 所有的import全部不使用,交给python3x.dll/libpython3.11.dylib执行
  • –follow-imports, 仅遵循通过import语句在代码中显式声明的导入。它不处理动态导入即importlib.import_module(‘modulename’)
  • –follow-import-to=need , need为你需要编译成C/C++的py文件夹名称,可以指定整个package,也可以是package下的某个模块
  • –include-package=mypackage : 导入某个包
  • –include-module=mypackage.mymodule : 导入包中某个模块

注意:推荐使用python完整安装的版本,不要使用pyenv安装的,否则面临一堆的编译问题。

python -m nuitka \
          --standalone \
          --onefile\
          --enable-plugin=pyqt5\
          --macos-create-app-bundle\
          --output-dir=build\
          --assume-yes-for-download\
          --macos-app-version=2.0\
          --disable-console\
          --include-data-dir=PyQt5/Qt5=PyQt5/Qt5  \
          calculator.py

或:

python3 -m nuitka --follow-imports --enable-plugin=pyside6 --standalone main.py

打包PyQt5应用:

~/anaconda3/bin/python -m nuitka --recurse-all --recurse-directory=./ main.py

示例: 打包PySide6应用

mkdir pyside6nuitka
cd pyside6nuitka/
python3 -m venv env

source env/bin/activate
pip install nuitka
pip install pyside6

pip list
Package    Version
---------- --------
Nuitka     0.6.16.2
pip        20.2.3
PySide6    6.1.2
setuptools 49.2.1
shiboken6  6.1.2

写一个简单的应用:

import sys
from PySide6.QtWidgets import QApplication
from PySide6.QtWidgets import QMainWindow
from PySide6.QtGui import QScreen

app = QApplication(sys.argv)
mainwindow = QMainWindow()
mainwindow.setGeometry(0, 0, 800, 600)
mainwindow.show()

app.exec()

打包:

python3 -m nuitka --follow-imports --enable-plugin=pyside6 --standalone main.py
Nuitka will make use of ccache to speed up repeated compilation.
Is it OK to download and put it in '/Users/loek/Library/Application Support/Nuitka/ccache/v4.2.1'.
No installer needed, cached, one time question.
Proceed and download? [Yes]/No

选No,然后:

Nuitka:INFO: Successfully created 'main.dist/main'.

执行:main.dist/main
发现报错:

ImportError: dlopen(../dev/pyside6nuitka/./main.dist/PySide6/QtWidgets.so, 2): Library not loaded: @rpath/QtQml.framework/Versions/A/QtQml
Referenced from: ..dev/pyside6nuitka/main.dist/libpyside6.abi3.6.1.dylib
Reason: image not found

在这里插入图片描述进入main.dist/PySide6,将venv环境中的pyside6nuitka/env/lib/python3.9/site-packages/PySide6/拷到main.dist/PySide6下即可。
在这里插入图片描述再运行就正常了。

参考链接

相关推荐

  1. 在Mac环境下打包Python应用

    2024-03-21 23:48:02       28 阅读
  2. 第10章:Electron应用打包分发

    2024-03-21 23:48:02       20 阅读
  3. Python实战:打包分发setup.py与pip

    2024-03-21 23:48:02       46 阅读
  4. Python打包

    2024-03-21 23:48:02       53 阅读
  5. python 打包

    2024-03-21 23:48:02       40 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-21 23:48:02       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-21 23:48:02       106 阅读
  3. 在Django里面运行非项目文件

    2024-03-21 23:48:02       87 阅读
  4. Python语言-面向对象

    2024-03-21 23:48:02       96 阅读

热门阅读

  1. 软件测试面试接口测试常见问题

    2024-03-21 23:48:02       45 阅读
  2. 【C语言】对称密码——栅栏的加密和解密

    2024-03-21 23:48:02       40 阅读
  3. 什么是虚拟dom

    2024-03-21 23:48:02       41 阅读
  4. Linux之shell文本搜索工具grep

    2024-03-21 23:48:02       41 阅读
  5. android VPN 数据包解析

    2024-03-21 23:48:02       47 阅读
  6. Python从入门到精通秘籍十一

    2024-03-21 23:48:02       43 阅读
  7. ARM day5

    2024-03-21 23:48:02       42 阅读
  8. Redis Pub/Sub: 实时消息传递的完美解决方案

    2024-03-21 23:48:02       45 阅读
  9. Python和FastAPI语义分析和文本图像

    2024-03-21 23:48:02       43 阅读