Python get path to executable file?
I'm very new to Python programming and I've cobbled together some code that will hopefully automatically rename a bunch files in a specific folder. I need to run this program on a computer without Python installed (it's not connected to the internet and I can't install python on it) so I've converted the .py file to a .exe file using auto-py-to-exe. The .py file works on my laptop, so the problem only shows up when I try to run the .exe file.
I use the path to the folder that the script is located in throughout the code so at the beginning of the script, I save the filepath as "path":
path = os.path.dirname(os.path.realpath(__file__))
However, when I convert the .py file to a .exe file and move that .exe file to another folder, the filepath that is saved in the 'path' variable is in a temp folder (probably the output location of the file converter). I tested it by isolating the part of the script that gets the filepath and making a .exe file to print just that filepath.
Is there a different way that I can get the filepath of the executable file? I don't want to hardcode the filepath into the program because people constantly reorganize the folders on that computer and I want this program to be flexible.
Here is the rest of the code if it's needed for context. Thank you and I'm sorry if this is a really basic question :)
# This section of code imports the modules used below
import os
import tkinter as tk
from tkinter import simpledialog
from tkinter import messagebox
# Setting global variables
path = os.path.dirname(os.path.realpath(__file__)) + "/" # This sets the filepath to the current folder
# Choosing the dough
dough_input = tk.Tk(className='Select dough')
dough_input.geometry('400x200')
# This is the code that creates the dough selection box. Any new types can be added here using the template below:
dough = tk.StringVar()
radiobutton_1 = tk.Radiobutton(dough_input, text='a', variable=dough, value="a", tristatevalue=0)
radiobutton_1.pack()
radiobutton_2 = tk.Radiobutton(dough_input, text='b', variable=dough, value="b", tristatevalue=0)
radiobutton_2.pack()
radiobutton_3 = tk.Radiobutton(dough_input, text='c', variable=dough, value="c", tristatevalue=0)
radiobutton_3.pack()
radiobutton_4 = tk.Radiobutton(dough_input, text='d', variable=dough, value="d", tristatevalue=0)
radiobutton_4.pack()
# This section of code saves the dough chosen and closes the pop-up window.
def submitfunction():
global bread
bread = dough.get()
dough_input.destroy()
submit = tk.Button(dough_input, text='Submit', command=submitfunction)
submit.pack()
# This section of code triggers the pop-up window for the dough selection.
dough_input.mainloop()
# Inputting the first number
root = tk.Tk()
root.withdraw()
user_inp = simpledialog.askinteger("Number Input", "Input first number:")
i = int(user_inp)
# Defining the file rename function
def rename():
global i # use the variable "i" defined above (The number that the user inputs)
for filename in os.listdir(path): # for each file in the folder specified above do the following
if ".sur" in filename:
my_dest = str(bread) + " " + str(i).zfill(4) + ".txt" # sets the new filename
my_source = path + filename # Defines the old filepath to the file
my_dest = path + my_dest # Defines the new filepath to the file
os.rename(my_source, my_dest) # rename function
i = i + 1 # advances the program down the list
messagebox.showinfo("Success", "All files have been renamed successfully!") # confirmation message!
# This function asks the user if the information they've input is correct. Once the user clicks "ok" the program runs
# the rename function.
def sanity_check():
file_list = os.listdir(path)
j = 0
for g in file_list:
if ".txt" in g:
j += 1
# This section of code does some calculations and creates a "sanity check" for the user. It takes the number that
# the user inputted above and sets that as the first number "i". Then it counts the number of files that
# meets the above criteria and sets that to the number of files. It uses that number of files to calculate the
# last number in the list. It then concatenates all this information and asks the user to
# confirm. If the user presses "ok" then the program
# proceeds with the rename. If the user presses cancel, the program aborts.
first_num = i
num_files = j
length_files = int(num_files) - 1
last_file = i + length_files
last_num = last_file
check = str(
"There are " + str(num_files) + " files in this folder. The dough analyzed is " + str(
dough) + ". The first "
"number is " + str(first_num).zfill(
4) + " and the last number is " + str(
last_num).zfill(4) + ". Is this correct?")
# This is the section of code that asks the user to verify the numbers.
confirmation = messagebox.askokcancel("Sanity Check!", check)
if confirmation == False:
messagebox.showerror("", "Program Cancelled")
else:
rename()
# This is the command that runs the program.
sanity_check()
Solution 1:
I think, os.getcwd()
and sys.executable
is what you are looking for.
With these 2 functions you will know the folder you'r script running in (from where you started it), and the path to a current python executable (which probably will be included in a .exe distribution, and unpacked to a tmp dir):
$> mkdir -p /tmp/x
$> cd /tmp/x
$> pwd
/tmp/x
$> which python
/usr/bin/python
$> python
Python 3.9.5 (default, May 24 2021, 12:50:35)
[GCC 11.1.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.getcwd()
'/tmp/x'
>>> import sys
>>> sys.executable
'/usr/bin/python'
>>>