I use this bit of code in my script to pinpoint, in a cross-platform way, where exactly it's being run from:
SCRIPT_ROOT = os.path.dirname(os.path.realpath(__file__))
Pretty simple. I then go on to use SCRIPT_ROOT
in other areas of my script to make sure everything is properly relative. My problem occurs when I run it through py2exe, because the generated executable doesn't set __file__
, therefore my script breaks. Does anyone know how to fix or work around this?
To determine application path in a Python EXE generated by pyInstaller, we can check the sys. frozen property. If the value is True , then the script code is running in the exe file.
getcwd() method. The os. getcwd() method is used for getting the Current Working Directory in Python. The absolute path to the current working directory is returned in a string by this function of the Python OS module.
py2exe doesn't support on Linux or Mac, as it's aimed to create .exe files which is a Windows-unique format. You can download a Windows virtual machine on both Mac and Linux, use Wine or use a different tool like Pyinstaller on Linux, or py2app on Mac.
Here is the py2exe documentation reference and here are the relevant items:
sys.executable
is set to the full pathname of the exe-file. sys.argv
is the full pathname of the executable, the rest are the command line arguments. sys.frozen
only exists in the executable. It is set to "console_exe" for a console executable, to "windows_exe" for a console-less gui executable, and to "dll" for a inprocess dll server. __file__
is not defined (you might want to use sys.argv[0] instead) It is not apparent from those docs whether "the exe-file" and "the executable" are the same thing, and thus whether sys.executable
and sys.argv[0]
are the same thing. Looking at code that worked for both script.py and py2exe_executable.exe last time I had to do this, I find something like:
if hasattr(sys, 'frozen'):
basis = sys.executable
else:
basis = sys.argv[0]
required_folder = os.path.split(basis)[0]
As I say that worked, but I don't recall why I thought that was necessary instead of just using sys.argv[0]
.
Using only basis
was adequate for the job in hand (read files in that directory). For a more permanent record, split something like os.path.realpath(basis)
.
Update Actually did a test; beats guesswork and armchair pontification :-)
Summary: Ignore sys.frozen, ignore sys.executable, go with sys.argv[0] unconditionally.
Evidence:
=== foo.py ===
# coding: ascii
import sys, os.path
print 'sys has frozen:', hasattr(sys, 'frozen')
print 'using sys.executable:', repr(os.path.dirname(os.path.realpath(sys.executable)))
print 'using sys.argv[0]:', repr(os.path.dirname(os.path.realpath(sys.argv[0] )))
=== setup.py ===
from distutils.core import setup
import py2exe
setup(console=['foo.py'])
=== results ===
C:\junk\so\py2exe>\python26\python foo.py
sys has frozen: False
using sys.executable: 'C:\\python26'
using sys.argv[0]: 'C:\\junk\\so\\py2exe' # where foo.py lives
C:\junk\so\py2exe>dist\foo
sys has frozen: True
using sys.executable: 'C:\\junk\\so\\py2exe\\dist'
using sys.argv[0]: 'C:\\junk\\so\\py2exe\\dist' # where foo.exe lives
Py2exe does not define __file__
: http://www.py2exe.org/index.cgi/Py2exeEnvironment
The OP requested a py2exe friendly version of:
SCRIPT_ROOT = os.path.dirname(os.path.realpath(__file__))
The best answer is to determine if python is frozen in an exe, py2exe has documentation on this: http://www.py2exe.org/index.cgi/HowToDetermineIfRunningFromExe
import imp, os, sys
def main_is_frozen():
return (hasattr(sys, "frozen") or # new py2exe
hasattr(sys, "importers") # old py2exe
or imp.is_frozen("__main__")) # tools/freeze
def get_main_dir():
if main_is_frozen():
return os.path.dirname(sys.executable)
return os.path.dirname(os.path.realpath(__file__))
SCRIPT_ROOT = get_main_dir()
Since, the python is EAFP, here's an EAFP version ...
try:
if sys.frozen or sys.importers:
SCRIPT_ROOT = os.path.dirname(sys.executable)
except AttributeError:
SCRIPT_ROOT = os.path.dirname(os.path.realpath(__file__))
Cheers!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With