python -m py_compile py文件绝对路径 pyc会生成在目录下的__pycache__下(前后有双下划线) 生成的文件名命名方式:源文件名.cpython-python版本.pyc
compile_dir(dir[, maxlevels[, ddir[, force[, rx[, quiet]]]]]) 参数含义: – maxlevels:递归编译的层数 – ddir:If ddir is given, it is prepended to the path to each file being compiled for use in compilation time tracebacks, and is also compiled in to the byte-code file, where it will be used in tracebacks and other messages in cases where the source file does not exist at the time the byte-code file is executed. – force:如果True,不论是是否有pyc,都重新编译 – rx:一个正则表达式,排除掉不想要的目录 – quiet:如果为True,则编译不会在标准输出中打印信息 python -m compileall <dir>2.打包为exe
pip install pyinstallerpyinstaller将单个py文件打包
Pyinstaller -F demo.py -- 打包exe Pyinstaller -F -w demo.py -- 不带控制台的打包 不带黑框 Pyinstaller -F -i test.ico demo.py -- 打包指定exe图标打包 常用选项: -h,–help 查看该模块的帮助信息 -F,-onefile 产生单个的可执行文件 -D,–onedir 产生一个目录(包含多个文件)作为可执行程序 -a,–ascii 不包含 Unicode 字符集支持 -d,–debug 产生 debug 版本的可执行文件 -w,–windowed,–noconsolc 指定程序运行时不显示命令行窗口(仅对 Windows 有效) -c,–nowindowed,–console 指定使用命令行窗口运行程序(仅对 Windows 有效) -o DIR,–out=DIR 指定 spec 文件的生成目录。如果没有指定,则默认使用当前目录来生成 spec 文件 -p DIR,–path=DIR 设置 Python 导入模块的路径(和设置 PYTHONPATH 环境变量的作用相似)。也可使用路径分隔符(Windows 使用分号,Linux 使用:号)来分隔多个路径 -n NAME,–name=NAME 指定项目(产生的 spec)名字。如果省略该选项,那么第一个脚本的主文件名将作为 spec 的名字 -i 选择图标pyinstaller将多个py文件打包
# -*- mode: python ; coding: utf-8 -*- block_cipher = None #设置 加密,需要安装tinyaes第三方库,最多16位字符,此处在使用--key= 会有变化 a = Analysis( ['demo.py'], # 运行的所有py文件,包括依赖的py文件 pathex=[], # 搜索导入的路径列表(此列表为项目绝对路径),包括选项给出的路径--paths,项目需要从什么地方导入自定义库 binaries=[], # 脚本需要的非python模块,包括--add-binary选项给出的名称,二进制数据 datas=[], # 应用程序中包含的非二进制文件,包括--add-data选项给出的名称,项目需要用到什么数据,比如图片,视频等。里面格式为tuple,第一个参数是文件路径,第二个是打包后所在的路径,其为一个元组:('image/*.png','data/image') hiddenimports=[], # 假如打包后打开exe显示module not found,就要把该库添加到hiddenimports里面了 hookspath=[], hooksconfig={}, # 挂钩配置选项由一个字典组成 runtime_hooks=[], excludes=[], # 假如你用的python有很多库,但是你不需要用到某个,那么就把它添加到里面去,可以压缩文件大小 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, [], exclude_binaries=True, # 是否排除二进制文件,为True时,为排除二进制的文件,当文件交大时包含二进制文件运行较快,如果是单文件,则没有这个选项 name='demo', # 打包程序的名字 debug=False, # 是否启用调试功能 bootloader_ignore_signals=False, # runtime_tmpdir=None, # 生成单文件时需要这个参数,定义运行时的临时文件夹 strip=False, upx=True, # 打包的时候进行压缩,False表示不压缩;要用到一个压缩程序UPX,用于压缩文件,需要单独下载 console=True, # 打包后的可执行文件双击运行时屏幕会出现一个cmd窗口,不影响原程序运行,等于是是否加-w参数 disable_windowed_traceback=False, argv_emulation=False, target_arch=None, codesign_identity=None, entitlements_file=None, """添加选项,初始化时没有的""" icon="", # 指定应用程序的图标,传入路径,可以相对路径 ) coll = COLLECT( """ 如果是单文件模式,不需要这个COLLECT类,同时需要将: a.binaries, a.zipfiles, a.datas, 这些数据文件添加到EXE中 """ exe, a.binaries, a.zipfiles, a.datas, strip=False, upx=True, upx_exclude=[], name='main', )项目打包:
pyinstaller demo.spec这样即可将python程序打包成一个独立的应用工具,直接运行即可。实现了保护程序的一个作用(当然也是可以反编译成功的,不过也提升了破解的难度)
nuitka --mingw64 xxx.py # 单纯打包 nuitka --mingw64 --standalone --show-progress --show-memory --enable-plugin=pyqt5 --output-dir=out demo.py # 指定参数打包 选项说明: --mingw64:环境选择 --standalone:是否独立环境 --show-progress:展示过程 --show-memory:显示内存 --plugin-enable=qt-plugins:qt配置 --include-qt-plugins=sensible,styles:qt样式保持 --recurse-all:导入引入的资源nuitka打包并不像网上说的那样,打包速度快,打包体积小。我也实测过,目前体检的感觉就是资源方面的确不用我们考虑那么深,不像pyinstaller可能相关配置就弄好了,打包还是会报资源缺失。而且打包的速度比较慢,体积也挺大的,但是毕竟也是可达到保护Python程序的目的,给使用者方便。
python pyobfuscate.py demo.py > demo_obfuscated.py两种主要都是对类和函数名等进行了重置替换,增加阅读难度
def hello(): print('hello')编写setup.py:
from distutils.core import setup from Cython.Build import cythonize setup(name='Hello World app', ext_modules=cythonize('hello.pyx'))编译为.c,再进一步编译为.so或.pyd:
python setup.py build_ext --inplace python -c "from hello import hello;hello()" # 即可直接引用生成的二进制文件中的hello()函数。生成的二进制 .so 或 .pyd 文件难以破解同时带来了性能提升
安装:
pip install pyarmor使用 obfuscate 选项对代码进行加密:
pyarmor obfuscate demo.py使用 licenses 选项生成许可文件:
pyarmor licenses \ --expired "2023-03-11" \ --bind-disk "10030SFTUF3NJ5T" \ --bind-mac "56:f1:a7:64:f0:64" \ --bind-ipv4 "211.110.6.54" \ r001使用 pack 选项即可打包脚本:
pyarmor pack demo.py不过这款工具属于试用阶段,倾向于商业模式,可以学习试试。