Python转exe后无法调用依赖.py脚本问题求助
解决PyInstaller打包后调用依赖脚本找不到文件的问题
问题根源
- 打包后程序运行时的工作目录不一定是exe所在目录,直接用相对路径
2table.py会找不到文件。 - 用
call(["python", "xxx.py"])的方式依赖系统安装的Python,若目标机器没装Python会直接失败,且脚本路径未对应到正确位置。 - 即使把脚本加入打包,PyInstaller会将其放到临时缓存目录,而非exe所在的外部目录。
方案一:修复路径,确保脚本在exe同目录运行
步骤1:修改主程序代码,获取正确的脚本路径
用sys.argv[0]获取exe的绝对路径,再拼接依赖脚本的路径,同时改用sys.executable调用Python(打包后会指向PyInstaller自带的Python解释器):
from subprocess import call from tkinter import ttk import tkinter as Tk import tkinter.messagebox as mb import os import sys def get_script_path(script_name): # 获取当前exe所在目录 if getattr(sys, 'frozen', False): # 打包后的环境 base_path = os.path.dirname(sys.executable) else: # 开发环境 base_path = os.path.dirname(os.path.abspath(__file__)) return os.path.join(base_path, script_name) root=Tk.Tk() root.title("Title") frm = ttk.Frame(root, padding=100) frm.grid() def table2(): script_path = get_script_path("2table.py") # 用sys.executable调用,确保使用打包时的Python环境 call([sys.executable, script_path]) mb.showinfo("info", "Success!") def table3(): script_path = get_script_path("3table.py") call([sys.executable, script_path]) mb.showinfo("info", "Success!") ttk.Button(frm, text="2 - table", command=table2).grid(column=2, row=0) ttk.Button(frm, text="3 - table ", command=table3).grid(column=2, row=2) ttk.Button(frm, text="Quit", command=root.destroy).grid(column=4, row=1) root.mainloop()
步骤2:打包命令
如果要把2table.py和3table.py一起打包到exe同目录(或让用户手动放到同目录),打包时用--add-data参数:
# Windows系统 pyinstaller --onefile --add-data "2table.py;." --add-data "3table.py;." main.py # macOS/Linux系统 pyinstaller --onefile --add-data "2table.py:." --add-data "3table.py:." main.py
打包后,exe会自动把这两个脚本释放到同目录,运行时就能找到。
方案二:将依赖脚本作为模块导入(更推荐)
把2table.py和3table.py改成可导入的模块,直接在主程序中调用,避免subprocess的路径问题:
步骤1:修改依赖脚本
比如在2table.py末尾添加:
# 2table.py def main(): # 原来的脚本逻辑写在这里 print("Running 2table.py") if __name__ == "__main__": main()
3table.py同理。
步骤2:修改主程序代码
直接导入并调用主函数:
from tkinter import ttk import tkinter as Tk import tkinter.messagebox as mb # 导入依赖脚本 import 2table import 3table root=Tk.Tk() root.title("Title") frm = ttk.Frame(root, padding=100) frm.grid() def table2(): 2table.main() mb.showinfo("info", "Success!") def table3(): 3table.main() mb.showinfo("info", "Success!") ttk.Button(frm, text="2 - table", command=table2).grid(column=2, row=0) ttk.Button(frm, text="3 - table ", command=table3).grid(column=2, row=2) ttk.Button(frm, text="Quit", command=root.destroy).grid(column=4, row=1) root.mainloop()
步骤3:打包命令
直接打包主程序即可,PyInstaller会自动检测并包含导入的模块:
pyinstaller --onefile main.py
这种方式不需要额外处理路径,也不依赖系统Python环境,兼容性更好。
内容的提问来源于stack exchange,提问作者Arlen B
相关产品推荐
相关产品推荐

