にゃん分間待ってやる

「文章の書き方」や「アクセスアップ」などブログ運営のテクニックを解説。

Pythonをexe化したときの実行パスを取得する方法

    <!-- more -->

Pythonをexe化したときの実行パスを取得する方法

適当なサンプルプログラムを作って、test.pyというファイル名で保存して
PyInstallerを使って、test.exeというファイルを生成

あとはtest.exeをダブルクリックすればプログラムが走るはずなんだけどなぜかうまく動作しない

そういうときはファイルのパスが問題になっている場合が多いです

PyInstallerで生成した.exeファイルはTEMP\_MEI62562みたいな変なパスで実行される

import sys
from tkinter import messagebox

messagebox.showinfo('パスの確認', '__file__\n{}'.format(__file__))

たとえば上記のpythonプログラムをtest.pyという名前で保存して
「C:\exp」というディレクトリで実行すると
想定通り、「C:\exp」というディレクトリで「test.py」が実行されます

パスの確認「__file__ test.py」

パスの確認「__file__ test.py」

しかし、「test.py」をPyInstallerでexe化して
「C:\exp」というディレクトリで実行すると
「C:\Users\taro\AppData\Local\Temp\_MEI62562」みたいな謎のディレクトリで「test.py」が実行されます

これは、.exeを実行したときに、ユーザーの「AppData\Local\Temp」に「_MEI62562」のような一時ディレクトリを作成して、そこにファイルを解凍してexe化する前のファイル群を再現してから内部的にtest.pyが実行されているからです
※_MEI62562の部分の数字は毎回異なる

パスの確認「__file__ test.exe」

パスの確認「__file__ test.exe」

pythonからseleniumを使ってChromeを操作するときなどに
chrome.exeやchromedriver.exeのパスを相対的に指定していると
「C:\Users\taro\AppData\Local\Temp\_MEI62562」というディレクトリには
chrome.exeが存在しないので、chromeを起動するところで「パスが存在しません」みたいなエラーでこけるのです

sys.argv[0]で.exeの実行パスを取得できる

import sys
from tkinter import messagebox

messagebox.showinfo('パスの確認', 'sys.argv[0]\n{}'.format(sys.argv[0]))

test.pyの中に上記を書いて
「C:\exp」というディレクトリで実行すると
以下のような表示になります

パスの確認「sys.argv[0] test.py」

パスの確認「sys.argv[0] test.py」

「test.py」をPyInstallerでexe化して
「C:\exp」というディレクトリで実行すると
以下のような表示になります

バスの確認「sys.argv[0] test.exe」

バスの確認「sys.argv[0] test.exe」

というわけで、sys.argv[0]という変数を使えば
test.exeのパスが取得できるので
pythonのコードの中で相対パスを使うときには

browser_path = os.path.join(sys.argv[0], 'browser', 'chrome.exe')

みたいにsys.argv[0]を起点にしてやれば簡単にパスを指定できます

このページは移転しました。