-
环境
python3.8
pyinstaller4.5.1 -
问题
项目中有一行 动态获取绝对路径的代码.self.absPath = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
打包后执行报错:
FileNotFoundError: [Errno 2] No such file or directory: '/tmp/_MEIDpU2rE/config/project.yaml'
简化问题, 发现是
__file__
的原因, 简化为以下代码print(__file__)
打包执行后输出为:
/tmp/_MEIxhhoGS/test.py
-
解决
- 1.版本问题
- 后面怀疑是python版本的问题 试了 python3.6+pyinstaller4.5.1 输出还是一样, 排除Python版本的影响;应该是 pyinstaller 版本的问题。
遂分别从高到低试了 4.9、 4.8、 4.7、 4.6、 4.5、 4.4、4.3、4.2、 4.1版本 发现 pyinstaller > 4.2 的版本会出现 打包后__file__
非真实目录的问题, pyinstaller <= 4.2版本正常 - 结论: 使用
pyinstaller<=4.2
的版本
- 后面怀疑是python版本的问题 试了 python3.6+pyinstaller4.5.1 输出还是一样, 排除Python版本的影响;应该是 pyinstaller 版本的问题。
- 2.另辟蹊径
- sys.executable
- python.exe 解释器的位置
- 打包的原理是将 python.exe也一起打包进来,所以只要找到解释器的位置也就找到文件的位置了
- 代码
def app_path(): if hasattr(sys, 'frozen'): # 可执行文件走这里 return os.path.dirname(sys.executable) return os.path.dirname(__file__) # 源码走这里
- 或者: 官网给出的范例
#!/usr/bin/env python3 import sys, os frozen = 'not' if getattr(sys, 'frozen', False): # we are running in a bundle frozen = 'ever so' bundle_dir = sys._MEIPASS else: # we are running in a normal Python environment bundle_dir = os.path.dirname(os.path.abspath(__file__)) print( 'we are',frozen,'frozen') print( 'bundle dir is', bundle_dir ) print( 'sys.argv[0] is', sys.argv[0] ) print( 'sys.executable is', sys.executable ) print( 'os.getcwd is', os.getcwd() )
- 代码
- sys.executable
- 1.版本问题
pyinstaller可执行文件__file__失效
于 2022-03-01 16:24:33 首次发布