I am making games in Python. Since I am using Python3, I have to cx_Freeze my scripts into executables to let other people who don't have Python3 run the games. I've put the resources (textures, audio, files etc.) in a folder that was related to the script path. When I didn't cx_Freeze the script, I used __file__
to locate the script and use this to locate the resources and use them. But once frozen using cx_Freeze, this method doesn't work.
My question is, how can find the file path of a script after it is being frozen using cx_Freeze?
I've tried __file__
, os module and any other modules related to file paths.
path = str(__file__).split("/")
path.remove("My executable name")
path.remove("MacOS")
path = "/".join(path) + "/Resources/"
I expected to return my Resources folder, but __file__
only returns my home directory so this causes a traceback.
There is a section Using data files in the cx_Freeze documentation dedicated to this question, saying:
Applications often need data files besides the code, such as icons. Using a setup script, you can list data files or directories in the
include_files
option tobuild_exe
. They’ll be copied to the build directory alongside the executable. Then to find them, use code like this:def find_data_file(filename): if getattr(sys, 'frozen', False): # The application is frozen datadir = os.path.dirname(sys.executable) else: # The application is not frozen # Change this bit to match where you store your data files: datadir = os.path.dirname(__file__) return os.path.join(datadir, filename)
An alternative is to embed data in code, for example by using Qt’s resource system.
There is one further point to notice if you are using cx_Freeze version 5.1.0 or 5.1.1: packages will be included into a subdirectory lib
of the build directory of the frozen application, whereas they are in the main directory of the unfrozen application or in the site-packages
directory of the Python installation. If you refer to data files located in packages directories from the main application, you need to add this additionnal lib
to the relative path using e.g. os.path.join()
(or to remove it in the other direction).
In your case, however, I guess Resources
is simply a data directory, not a package with Python code. Then you only need to add 'Resources'
to the include_files
list in the setup script. To get a file named filename
located in the Resources
directory, the example code modified like this should do the job:
def find_data_file(filename):
if getattr(sys, 'frozen', False):
# The application is frozen
datadir = os.path.dirname(sys.executable)
else:
# The application is not frozen
datadir = os.path.dirname(__file__)
# The following line has been changed to match where you store your data files:
return os.path.join(datadir, 'Resources', filename)