Python 之 __file__ 變量導致打包 exe 后路徑輸出不一致的問題

現象

做項目的時候,一直使用 os.path.dirname(os.path.abspath(__file__)) 來獲取當前目錄。然而,最近卻遇到了一個路徑相關的問題。直接運行 py 文件是正常的,但是打包成 exe 之后,卻顯示因為路徑問題導致程序報錯無法繼續執行。

比如我有一段獲取當前目錄的腳本代碼:

test.py

import os
import timedef get_current_dir():return os.path.dirname(os.path.abspath(__file__))if __name__ == '__main__':current_dir = get_current_dir()print(current_dir)  # E:\lky_project\tmp_project\test_projecttime.sleep(10)

正常用 Python 解釋器執行的話輸出?E:\lky_project\tmp_project\test_project,看起來沒什么問題。

好,接下來,我用下面的命令對 test.py 打包,打包后將生成的 test.exe 移動到和 test.py 相同的目錄下(確保執行目錄一致)。

E:\lky_project\tmp_project\test_project> pyinstaller -F ./test.py

然后雙擊運行 test.exe,結果輸出的目錄卻是下面這種(看起來是個臨時目錄)。

顯然,這兩個輸出不是同一個目錄,而我中間只是做了打包的操作,并沒有對代碼進行任何額外修改,但為什么輸出的目錄卻不一樣呢?

原因

我搜了一下 DeepSeek,其中的分析我還是比較認同的,所以就不多說了。分析的原因如下:

  • __file__ 變量通常是指當前執行腳本的路徑。當直接運行腳本時,__file__ 會返回該腳本的文件名,然后通過 os.path.abspath 獲取絕對路徑,再取目錄名,得到的就是腳本所在的目錄路徑。這應該是正確的。
  • 但是當打包成 exe 后,比如使用 PyInstaller,情況可能會不同。PyInstaller 打包后的 exe 文件會將腳本解壓到一個臨時目錄中運行,這時候 __file__ 可能指向的是這個臨時目錄中的路徑,而不是原來的腳本位置。這就會導致 current_dir 在打包后得到的是臨時目錄的路徑,而不是用戶期望的 exe 所在的目錄。

解決

既然原因找到了,總得找個解決方案。

sys.frozen

其中一個解決方法,利用程序打包前和打包后 sys.frozen 環境變量的不同來進行區分,不同情況使用不同的目錄獲取方式。

import sys
import os
import timedef get_current_dir():if getattr(sys, 'frozen', False):# 打包后的情況,使用 sys.executable 的目錄print("frozen")return os.path.dirname(sys.executable)else:# 打包前,正常腳本執行print("not frozen")return os.path.dirname(os.path.abspath(__file__))current_dir = get_current_dir()
print(current_dir)time.sleep(10)

os.getcwd()

再有就是使用 os.getcwd() 來獲取當前目錄。

import os
import timedef get_current_dir():return os.path.abspath(os.getcwd())current_dir = get_current_dir()
print(current_dir)time.sleep(10)

pathlib

或者使用 pathlib 的?absolute() 或 resolve() 方法也可以。

import time
import pathlibdef get_current_dir():# return pathlib.Path("./").resolve()return pathlib.Path("./").absolute()current_dir = get_current_dir()
print(current_dir)time.sleep(10)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/77622.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/77622.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/77622.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

PH熱榜 | 2025-04-21

1. Google Whisk 2.0 標語:將圖像轉換為八秒的動畫短片。 介紹:Whisk 是谷歌實驗室的一項新創新,現在推出了 Whisk Animate——它可以將你的圖片轉換成生動的8秒視頻,采用了 Veo 2 技術。此功能現已在60多個國家的 Google One A…

AI大模型 —— 國產大模型 —— 華為大模型

有這么一句話,那就是AI大模型分兩種,一種是大模型;另一種是華為大模型。 如果從技術角度來分析,華為的技術不論是在軟件還是硬件都比國外的大公司差距極大,甚至有些技術評論者認為華為的軟硬件技術至少落后2.5代&#…

FPGA 中 XSA、BIT 和 DCP 文件的區別

在 FPGA(現場可編程門陣列)開發中,XSA、BIT 和 DCP 文件是常見的文件類型,它們在功能、用途、文件內容等方面存在明顯區別,以下是詳細介紹: 1. XSA 文件 定義與功能 XSA(Xilinx Shell Archiv…

MH2103系列coremark1.0跑分數據和優化,及基于arm2d的優化應用

CoreMark 1.0 介紹 CoreMark 是由 EEMBC(Embedded Microprocessor Benchmark Consortium)組織于 2009 年推出的一款用于衡量嵌入式系統 CPU 或 MCU 性能的標準基準測試工具。它旨在替代陳舊的 Dhrystone 標準(Dhrystone 容易受到各種libc不同…

云原生與AI的關系是怎么樣的?

云原生與AI的結合正在重塑現代應用的開發與部署模式,兩者相輔相成,共同推動技術創新與產業升級。以下是兩者的核心概念、結合點及未來趨勢的詳細解析: 一、云原生與AI的核心概念 云原生(Cloud Native) ? 定義&#…

【CentOs】構建云服務器部署環境

(一) 服務器采購 2 CPU4G 內存40G 系統盤 80G 數據盤 (二) 服務器安全組和端口配置 (三) 磁盤掛載 1 登錄 root 2 查看目前磁盤使用情況 df -h 3 查看磁盤掛載情況 識別哪些磁盤沒掛載 fdisk -l 4 對未掛載磁盤做分區 fdisk /dev/vdb 輸入m&#xff0…

LangChain4j語言模型選型指南:主流模型能力全景對比

LangChain4j語言模型選型指南:主流模型能力全景對比 前言 在大語言模型應用開發中,選擇合適的底層模型提供商是架構設計的關鍵決策。LangChain4j作為Java生態的重要AI框架,其支持的20模型提供商各有獨特的優勢場景。本文通過功能矩陣深度解…

2025.4.21日學習筆記 JavaScript String、Array、date、math方法的使用

1. String(字符串) String 對象用于處理和操作文本數據。 length:返回字符串的長度。 const str "Hello"; console.log(str.length); // 輸出: 5 charAt(index):返回指定索引位置的字符。 const str "Hello…

(14)VTK C++開發示例 --- 將點投影到平面上

文章目錄 1. 概述2. CMake鏈接VTK3. main.cpp文件4. 演示效果 更多精彩內容👉內容導航 👈👉VTK開發 👈 1. 概述 計算一個點在一個平面上的投影。 vtkPlane 是 VTK(Visualization Toolkit)庫中的一個類&…

電子電器架構 ---軟件定義汽車的電子/電氣(E/E)架構

我是穿拖鞋的漢子,魔都中堅持長期主義的汽車電子工程師。 老規矩,分享一段喜歡的文字,避免自己成為高知識低文化的工程師: 周末洗了一個澡,換了一身衣服,出了門卻不知道去哪兒,不知道去找誰,漫無目的走著,大概這就是成年人最深的孤獨吧! 舊人不知我近況,新人不知我過…

Android開發中的復制和粘貼

Android 提供了一個強大的基于剪貼板的框架,用于復制和粘貼。它支持簡單和復雜的數據類型,包括文本字符串、復雜數據結構、文本和二進制流數據,以及應用資源。簡單的文本數據直接存儲在剪貼板中,而復雜的數據則存儲為引用&#xf…

【STM32單片機】#10.5 串口數據包

主要參考學習資料: B站江協科技 STM32入門教程-2023版 細致講解 中文字幕 開發資料下載鏈接:https://pan.baidu.com/s/1h_UjuQKDX9IpP-U1Effbsw?pwddspb 單片機套裝:STM32F103C8T6開發板單片機C6T6核心板 實驗板最小系統板套件科協 實驗&…

百度暑期實習崗位超3000個,AI相關崗位占比87%,近嶼智能攜AIGC課程加速人才輸出

今年3月,百度重磅發布3000暑期實習崗位,聚焦大模型、機器學習、自動駕駛等AI方向的崗位比例高達87%。此次實習崗位涉及技術研發、產品策劃、專業服務、管理支持、政企解決方案等四大類別,覆蓋超300個崗位細分方向。值得一提的是,百…

vue3 + element-plus中el-dialog對話框滾動條回到頂部

對話框滾動條回到頂部 1、需要對話框顯示后 2、使用 nextTick 等待 Dom 更新完畢 3、通過開發者工具追查到滾動條對應的標簽及class“el-overlay-dialog” 4、設置屬性 scrollTop 0 或者 執行方法 scrollTo(0, 0) // 對話框顯示標識 const dialogVisible ref(false); //…

C++學習之游戲服務器開發十一DOCKER的基本使用

目錄 1.多實例部署方案 2.容器的概念 3.docker初識 4.docker倉庫 5.docker鏡像 6.docker容器 7.docker和虛擬機的區別 8.docker命令解釋 9.dockerfile構建鏡像 10.離線分發鏡像 1.多實例部署方案 redis 命令( redis-cli XXXX ) set key value:…

2025.4.21總結

工作:開了一場關于大模型版本的會議,回歸一個問題單,提了兩個單,把用例都執行完。如今都四月中旬了,上班年快要結束了,該到了沖刺KPI的時候了。 今日思考:刷到了jack叔叔的視頻,講了…

vite安裝及使用

沒特殊要求的項目,還是怎么簡單怎么來╮(╯▽╰)╭ 一、Vite 基礎知識 1. 什么是 Vite? Vite 是一個前端構建工具,專注于開發服務器速度和優化構建過程。特點: 快速冷啟動:利用 ES 模塊的原生支持,實現快速的開發服務器啟動。即時熱更新:在開發過程中,修改代碼后可以…

ubuntu下gcc/g++安裝及不同版本切換

1. 查看當前gcc版本 $ gcc --version# 查看當前系統中已安裝版本 $ ls /usr/bin/gcc*2. 安裝新版本gcc $ sudo apt-get update# 這里以版本12為依據(也可以通過源碼方式安裝,請自行Google!) $ sudo apt-get install -y gcc-12 g…

cdq 系列 題解

從二維數點&#xff08;二維偏序&#xff09;到三維偏序。 用 cdq 分治可以解決二維數點問題。 1.洛谷 P1908 逆序對 題意 求所有數對 ( i , j ) (i,j) (i,j) 的個數&#xff0c;滿足 i < j i<j i<j 且 a i > a j a_i>a_j ai?>aj?。 1 ≤ n ≤ 5 1…

計算機組成與體系結構:內存接口(Memory Interface)

目錄 什么是內存接口 &#xff1f; 為什么需要特別設計“接口”&#xff1f; 什么是 MIPS&#xff1f;為什么它和內存接口有關&#xff1f; 內存接口的兩種訪問方式 串行訪問&#xff08;Serial Access Model&#xff09; 并行訪問&#xff08;Parallel Access Model&…