Pyinstaller错误打包
——来自GPT老师
PyInstaller 打包后 pathlib.Path(__file__) 无法正确获取路径的原因与解决方案
💡 问题原因
当你使用 PyInstaller 的 --onefile(-F) 模式打包程序时,
PyInstaller 会在运行时自动将所有文件 临时解压 到一个随机生成的目录,例如:
C:\Users\<用户名>\AppData\Local\Temp\_MEI151002\
然后从这个临时目录中执行你的程序。
因此,执行以下代码时:
pathlib.Path(__file__)
返回的路径自然会是:
C:\Users\<用户名>\AppData\Local\Temp\_MEI151002\main.py
而不是你的项目原始目录。
✅ 正确的解决方案
要兼容 源码运行 与 打包运行 两种情况,应使用以下写法:
import sys
import pathlib
if getattr(sys, 'frozen', False):
# 如果是被打包的 exe 运行
app_path = pathlib.Path(sys.executable).parent
else:
# 如果是源码运行
app_path = pathlib.Path(__file__).parent
print("程序运行目录:", app_path)
说明:
sys.frozen是 PyInstaller 在运行时自动注入的标志。sys.executable指向当前可执行文件的完整路径。__file__仅在源码状态下可用。
🧱 示例修正版
import sys
import pathlib
class Functions:
def __init__(self):
self.key_path = r"Software\Microsoft\Windows\CurrentVersion\Run"
self.app_name = "DeviceUsageTime"
if getattr(sys, 'frozen', False):
# 打包后运行
self.app_path = pathlib.Path(sys.executable).parent
else:
# 源码运行
self.app_path = pathlib.Path(__file__).parent
print("当前程序路径:", self.app_path)
🧠 为什么 PyInstaller 这么做?
在 --onefile 模式下,PyInstaller 会:
- 将所有依赖文件压缩进一个 EXE。
- 启动时解压到
_MEIxxxxx临时文件夹。 - 从该文件夹运行虚拟环境。
- 程序退出后自动删除该文件夹。
因此,__file__ 永远会指向这个临时路径。
若要获取 真正的 EXE 所在目录(例如存放配置文件、日志、资源等),
请使用 sys.executable。
🧩 推荐封装:资源路径函数
可以定义一个通用函数,在源码和打包模式下都能正确找到文件路径:
def resource_path(relative_path):
"""获取资源文件的绝对路径,兼容打包和源码运行"""
import sys, pathlib
if getattr(sys, 'frozen', False):
base_path = pathlib.Path(sys.executable).parent
else:
base_path = pathlib.Path(__file__).parent
return base_path / relative_path
使用方式:
config_file = resource_path("config.json")
这样即使打包成 EXE,也能正确读取配置文件或资源文件。

浙公网安备 33010602011771号