How to get filename of the __main__ module in Python?

PythonPython Module

Python Problem Overview


Suppose I have two modules:

a.py:

import b
print __name__, __file__

b.py:

print __name__, __file__

I run the "a.py" file. This prints:

b        C:\path\to\code\b.py
__main__ C:\path\to\code\a.py

Question: how do I obtain the path to the __main__ module ("a.py" in this case) from within the "b.py" library?

Python Solutions


Solution 1 - Python

import __main__
print(__main__.__file__)

Solution 2 - Python

Perhaps this will do the trick:

import sys
from os import path
print(path.abspath(str(sys.modules['__main__'].__file__)))

Note that, for safety, you should check whether the __main__ module has a __file__ attribute. If it's dynamically created, or is just being run in the interactive python console, it won't have a __file__:

python
>>> import sys
>>> print(str(sys.modules['__main__']))
<module '__main__' (built-in)>
>>> print(str(sys.modules['__main__'].__file__))
AttributeError: 'module' object has no attribute '__file__'

A simple hasattr() check will do the trick to guard against scenario 2 if that's a possibility in your app.

Solution 3 - Python

The python code below provides additional functionality, including that it works seamlessly with py2exe executables.

I use similar code to like this to find paths relative to the running script, aka __main__. as an added benefit, it works cross-platform including Windows.

import imp
import os
import 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():
       # print 'Running from path', os.path.dirname(sys.executable)
       return os.path.dirname(sys.executable)
   return os.path.dirname(sys.argv[0])

# find path to where we are running
path_to_script=get_main_dir()

# OPTIONAL:
# add the sibling 'lib' dir to our module search path
lib_path = os.path.join(get_main_dir(), os.path.pardir, 'lib')
sys.path.insert(0, lib_path)

# OPTIONAL: 
# use info to find relative data files in 'data' subdir
datafile1 = os.path.join(get_main_dir(), 'data', 'file1')

Hopefully the above example code can provide additional insight into how to determine the path to the running script...

Solution 4 - Python

Another method would be to use sys.argv[0].

import os
import sys

main_file = os.path.realpath(sys.argv[0]) if sys.argv[0] else None

sys.argv[0] will be an empty string if Python gets start with -c or if checked from the Python console.

Solution 5 - Python

import sys, os

def getExecPath():
	try:
		sFile = os.path.abspath(sys.modules['__main__'].__file__)
	except:
		sFile = sys.executable
	return os.path.dirname(sFile)

This function will work for Python and Cython compiled programs.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRoman StarkovView Question on Stackoverflow
Solution 1 - PythonironfroggyView Answer on Stackoverflow
Solution 2 - PythonJarret HardieView Answer on Stackoverflow
Solution 3 - PythonpopcntView Answer on Stackoverflow
Solution 4 - PythonlrsjngView Answer on Stackoverflow
Solution 5 - PythonJamesView Answer on Stackoverflow