Pyinstaller打包后__file__定位当前绝对路径错误

写了个python脚本,想搞成crontab定时任务,为了方便管理依赖通过pyinstaller打包成可执行文件,但是发现打包后通过__file__变量读取值怎么都不都不是当前路径,最后通过GPT解决了这个问题,在此记录一下:

import datetime
import os
import sys

# 如果直接运行.py文件或打包后的可执行文件,time_log.txt就在当前文件夹
# 但如果cron 定时运行一定要指定绝对路径,相对路径写time_log.txt就会不知道飞到哪里去,由于log写到别的地方了,还没法看log debug
# filename = './time_log.txt'

# 聪明的你想到了使用python动态定位当前文件路径,但却发现pyinstller打包后下面这个路径其实在/tmp/_MEI7kCms2/
# current_file_path = os.path.abspath(__file__)
# current_directory = os.path.dirname(current_file_path)
# filename = os.path.join(current_directory, 'time_log.txt')


# chatGPT给了我如下方案,亲测有效
if getattr(sys, 'frozen', False):
    # 如果是打包后的可执行文件,则使用脚本文件目录,用于避免pyinstaller打包后的绝对路径问题
    current_directory = os.path.dirname(sys.executable)
else:
    # 如果是脚本文件, 则使用当前文件
    current_file_path = os.path.abspath(__file__)
    current_directory = os.path.dirname(current_file_path)

filename = os.path.join(current_directory, 'time_log.txt')


# 获取当前时间
current_time = datetime.datetime.now()

# 将当前时间格式化为字符串
formatted_time = current_time.strftime('%Y-%m-%d %H:%M:%S')

# 打开文件并追加时间
with open(filename, 'a') as file:
    file.write(formatted_time + '\n')

print(f'当前时间已写入到文件:{filename}')

代码逻辑

  • 打包后的可执行文件

    if getattr(sys, 'frozen', False):
        current_directory = os.path.dirname(sys.executable)
    

    如果脚本是打包后的可执行文件,__file__ 变量不可用,sys.frozen 为 True,此时 sys.executable 指向可执行文件本身的路径。通过 os.path.dirname(sys.executable),我们可以获取可执行文件所在的目录。这确保了我们在打包后的环境中能够正确定位到所需的文件和资源。

  • 普通 Python 脚本

    else:
        current_file_path = os.path.abspath(__file__)
        current_directory = os.path.dirname(current_file_path)
    

    如果脚本是作为普通的 Python 脚本运行,sys.frozen 为 False,此时我们使用 __file__ 获取当前脚本文件的路径。通过 os.path.abspath(__file__) 获取绝对路径,然后使用 os.path.dirname(current_file_path) 获取脚本文件所在的目录。这确保了在开发和调试时,脚本能够正确定位到所需的文件和资源。

总结

crontab要求在代码中写绝对路径

但pyinstaller打包后的python读取的所在文件绝对路径是/tmp, 而不是当前路径

所以分成两种情况,判断是否是打包后的文件,还是.py脚本获取当前文件夹,分情况获取路径

当您使用pyinstallerPython脚本打包成独立的可执行文件后遇到语法错误的问题,这通常涉及以下几个方面: ### 1. Python环境差异 **解释:** - **原生环境**:您的Python脚本是在安装了所有依赖包的环境中运行正常的。 - **目标环境**:在目标计算机上运行打包后的应用时,它缺少某些必要的库、版本不匹配或配置不一致导致错误。 **解决方案:** - 确保目标计算机也安装了相同的Python环境及其所有依赖。 - 使用`pyinstaller`的选项`--onefile`和`--upx-dir`等来优化打包过程,并确保所有需要的库都包含在打包结果内。 - 检查并添加缺失的环境变量,比如路径到所需库的目录。 ### 2. 特殊语法或第三方库问题 **解释:** 一些特定的Python语法或者第三方库函数,在目标系统中可能不支持或者存在兼容性问题。 **解决方案:** - 更新`requirements.txt`文件,列出所有依赖库及版本,使用统一的标准库版本。 - 如果涉及使用特定版本的第三方库,确保目标系统同样安装了此版本的库。 - 转换或替换可能导致问题的特殊语法或函数。 ### 3. 编译错误 **解释:** 打包过程中可能出现编译错误,特别是对于依赖于C语言扩展的模块。 **解决方案:** - 检查编译设置,确保`pyinstaller`能够正确处理所有需要编译的C扩展。 - 查看编译日志定位错误信息,针对错误采取修复措施,如更新编译工具链、调整C编译选项等。 ### 4. 未初始化的全局变量或资源管理不当 **解释:** 如果您的代码中有未初始化的全局变量或其他资源泄漏问题,在打包后可能会因为这些未处理的部分而导致程序崩溃或异常。 **解决方案:** - 对所有全局变量和资源进行适当的初始化和清理工作,避免内存泄露。 - 遵循良好的编码实践,确保每个函数都能安全地终止,释放其占用的所有资源。 ### 相关问题: 1. **如何确保打包后的应用程序兼容所有目标操作系统?** 2. **在使用pyinstaller打包时,应如何处理依赖外部库的情况?** 3. **为什么在我的项目中使用pyinstaller后,某些特有功能在其他环境中无法重现?** 通过细致检查上述几个常见原因,并针对性地解决问题,可以有效解决pyinstaller打包后遇到的语法错误问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值