When packaged to a single file with PyInstaller, running the .exe will unpack everything to a folder in your TEMP directory, run the script, then discard the temporary files. The path of the temporary folder changes with each running, but a reference to its location is added to sys
as sys._MEIPASS
.
To make use of this, when your Python codes reads any file that will also be packaged into your .exe, you need to change the files location to be located under sys._MEIPASS
. In other words, you need to add it to your python code.
Here is an example that using the code from the link you referenced to adjust the file path to correct location when packaged to a single file.
Example
# data_files/data.txt
hello
world
# myScript.py
import sys
import os
def resource_path(relative_path):
""" Get absolute path to resource, works for dev and for PyInstaller """
try:
# PyInstaller creates a temp folder and stores path in _MEIPASS
base_path = sys._MEIPASS
except Exception:
base_path = os.path.abspath(".")
return os.path.join(base_path, relative_path)
def print_file(file_path):
file_path = resource_path(file_path)
with open(file_path) as fp:
for line in fp:
print(line)
if __name__ == '__main__':
print_file('data_files/data.txt')
Running PyInstaller with the following options packages the file:
pyinstaller --onefile --add-data="data_files/data.txt;data_files" myScript.py
builds myScript.exe which runs correctly and can open and read the packaged data file.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…