python 打包 exe

目录

一、安装包

二、打包命令

​编辑

​编辑

三、报错

总结


一、安装包

pip install Pyinstaller

二、打包命令

Pyinstaller -F -w 文件名.py

 

https://www.jb51.net/article/109195.htm

三、报错

Fatal error: PyInstaller does not include a pre-compiled bootloader for your
platform. For more details and instructions how to build the bootloader see

这个问题的具体原因我也不知道,看了很多文章都没有解决。直到这一篇:Pyinstaller缺少引导加载程序

我创建了个新的虚拟环境,下载pyinstaller源码包安装(python setup.py install) 然后在打包,就可以了。


总结

自动打包代码

# coding=utf-8
'''
@date:2023/11/24 12:58
@mail:xiaochun235@qq.com
@Content: 打包
'''
# coding=utf-8
import os
import shutil
import traceback
import platform
import subprocess
import sys
from common import *
import time
import zipfile

# 获取当前目录的上上层
BASE_PATH = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
# 当前目录
config_path = os.path.join(os.path.abspath(os.path.dirname(__file__)),'config.yaml')
if os.path.exists(config_path):
	CURRENT_PATH = os.path.abspath(os.path.dirname(__file__))
else:
	CURRENT_PATH = BASE_PATH
print("CURRENT_PATH:", CURRENT_PATH)


PROJECT_NAME="selenium自动化执行"
# 删除文件内容
delete_files = ["build", "dist", "bin.spec",f'{PROJECT_NAME}']
PYTHON_VENV_PATH = 'D:/pthon_venv/selenium_project_venv/Lib/site-packages'
# 需要复制的文件及其 文件夹名
copy_file_name_list=['config.yaml','chrome_win32',f'dist/{PROJECT_NAME}/{PROJECT_NAME}.exe',f'dist/{PROJECT_NAME}/{PROJECT_NAME}.bat',f'dist/{PROJECT_NAME}/_internal']
# 打包的 python 文件
pack_python_file_name='main.py'
# 打包文件名
shijian=time.strftime("%Y-%m-%d%H%M%S", time.localtime())
GET_CURRENT_FILES = CURRENT_PATH
# 目标目标文件
TARGET=os.path.join(CURRENT_PATH,PROJECT_NAME) #目标目录
# cmd 运行命令
def run_pack(instructions):
	system_return = os.system(instructions)
	print(system_return)
	return system_return


# 删除原来报道好的文件
def delete_file(delete_files):
	print("获取当前文件夹路径:", GET_CURRENT_FILES)
	files = os.listdir(GET_CURRENT_FILES)
	print("当前文件目录下的所有文件及其文件夹名称", files)
	print("需要删除的文件为", delete_files)
	# 循环删除文件
	for x in files:
		if x in delete_files:
			file_path = os.path.join(GET_CURRENT_FILES, x)
			try:
				if os.path.isdir(file_path):  # 判断是否是文件夹
					# 删除不支持删除文件 只能删除文件夹
					try:
						shutil.rmtree(file_path)
					except Exception as e:
						logger.error(f"删除文件报错{file_path}")
				else:
					# # 删除单个文件夹
					os.remove(os.path.join(GET_CURRENT_FILES, x))
			except Exception as e:
				print("文件不存在")
				print(traceback.format_exc())
			finally:
				pass


# 创建文件 dat
def create_a_file(file_path, file_content):
	t = open(file_path, mode='w')
	t.write(file_content)


# 判断 PiP包是否存在
def is_existence_package(instructions):
	read_cmd = os.popen(f"pip show {instructions}").read()
	read_cmd_list = read_cmd.split("\n")
	arr_list = []
	for x in read_cmd_list:
		list_kv = x.split(": ")
		arr_list += list_kv
	keys = []
	vlu = []
	for x in range(0, len(arr_list)):
		if x % 2 == 0:
			keys.append(arr_list[x])
		else:
			vlu.append(arr_list[x])
	kv = zip(keys, vlu)
	version_dict = dict(kv)
	if version_dict.get("Version"):
		return True
	else:
		return False


# 打开文件夹
def open_fp(fp: str):
	"""
	打开文件或文件夹
	优点: 代码输入参数少, 复制粘贴即可使用, 支持在mac和win上使用, 打开速度快稳定;
	:param fp: 需要打开的文件或文件夹路径
	"""
	systemType: str = platform.platform()  # 获取系统类型
	if 'mac' in systemType:  # 判断以下当前系统类型
		fp: str = fp.replace("\\", "/")  # mac系统下,遇到`\\`让路径打不开,不清楚为什么哈,觉得没必要的话自己可以删掉啦,18行那条也是
		subprocess.call(["open", fp])
	else:
		fp: str = fp.replace("/", "\\")  # win系统下,有时`/`让路径打不开
		os.startfile(fp)


# 初始化
def init_program():
	# 删除文件

	delete_file(delete_files)
	# 安装包
	if not is_existence_package("Pyinstaller"):
		run_pack("pip install Pyinstaller")
	# 打包需要额外打包的内容 虚拟环境pip 包
	xu_ni_huanjing = PYTHON_VENV_PATH
	# 打包后的名称
	sheng_cheng_name = PROJECT_NAME
	# 打包图标
	ico = "favicon.ico"
	'''
	-F 生成结果是一个 exe 文件,所有的第三方依赖、资源和diamante均被打包进该 exe 内
	-D 生成结果是一个目录,各种第三方依赖、资源和exe 同时存储在该目录(默认)
	-a 不包含 unicode 支持
	-d 执行的 exe 时间 ,会输出一些 log ,有助于查错
	-w 不显示命令行窗口
	-c 显示命令行窗口 (默认)
	-p 指定额外的  import 路径,类似于使用 python path
	-i 指定图标
	-v 显示版本号
	-n 生成 .exe 的文件名
	'''
	# instructions = f"Pyinstaller -p {xu_ni_huanjing} -i {ico} {pack_python_file_name} -n {sheng_cheng_name} -w"
	instructions = f"Pyinstaller -p {xu_ni_huanjing} -i {ico} {pack_python_file_name} -n {sheng_cheng_name}"
	i = run_pack(instructions)
	# 创建bat文件
	if i == 0:
		file_content = f".\\{sheng_cheng_name}.exe"
		file_path = f"dist/{sheng_cheng_name}/{sheng_cheng_name}.bat"
		create_a_file(file_path, file_content)
	# 复制模板到指定的位置
	fuXhiWengJian(copy_file_name_list, TARGET)
	# 重命名文件夹名称
	parent_path = os.path.dirname(TARGET)
	old_folder_name = TARGET #文件夹名称'
	new_folder_name = os.path.join(parent_path,PROJECT_NAME)#'新文件夹名称'
	os.rename(old_folder_name, new_folder_name)
	# 将文件打包为zip
	logger.info(f"正在为你压缩{new_folder_name}")
	zip_folder(new_folder_name,os.path.join(os.path.dirname(new_folder_name),f'{PROJECT_NAME}{shijian}.zip'))
	logger.info(f"压缩完成{os.path.join(os.path.dirname(new_folder_name),f'{PROJECT_NAME}{shijian}.zip')}")
	## 打开文件夹路径
	open_fp(new_folder_name)
	delete_file(["build", "dist", "bin.spec"])


# 复制到目标文件
# shutil.copy() 复制文件
def fuXhiWengJian(copy_file_name_list, target):
	'''
	:param source: 需要复制的文件及文件目录
	:param target: 复制到我目标位置
	:return:
	'''
	# 循环复制
	if not os.path.exists(target):
		os.makedirs(target)  # 创建路径 创建多层目录
	for name in copy_file_name_list:
		source = os.path.join(CURRENT_PATH,name)
		if os.path.isdir(source):
			try:
				last_dir = os.path.split(source)[-1]
				shutil.copytree(source, os.path.join(target,last_dir))
			except FileExistsError as e:
				logger.error(msg=f"复制文件报错:{e}")
		else:
			shutil.copy2(source, target)
# 将文件夹压缩
def zip_folder(folder_path, output_path):
	'''
	:param folder_path: 要压缩的文件夹路径
	:param output_path: 输出的zip文件路径
	:return: 
	'''
	with zipfile.ZipFile(output_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
		for root, dirs, files in os.walk(folder_path):
			for file in files:
				zipf.write(os.path.join(root, file), os.path.relpath(os.path.join(root, file), folder_path))

if __name__ == "__main__":
	init_program()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值