Reputation: 1050
how should I define a function, where
,which can tell where it was executed, with no arguments passed in?
all files in ~/app/
a.py:
def where():
return 'the file name where the function was executed'
b.py:
from a import where
if __name__ == '__main__':
print where() # I want where() to return '~/app/b.py' like __file__ in b.py
c.py:
from a import where
if __name__ == '__main__':
print where() # I want where() to return '~/app/c.py' like __file__ in c.py
Upvotes: 6
Views: 539
Reputation: 3207
import sys
if __name__ == '__main__':
print sys.argv[0]
sys.argv[0] is always the name/path of the file running, even with no arguments passed in
Upvotes: 1
Reputation: 41940
Based on this...
print where() # I want where() to return '~/app/b.py' like __file__ in b.py
...it sounds more like what you want is the qualified path of the script you're executing.
In which case, try...
import sys
import os
if __name__ == '__main__':
print os.path.realpath(os.path.join(os.getcwd(), os.path.expanduser(__file__)))
Using realpath()
should cope with the case where you're running the script from a symbolic link.
Upvotes: 0
Reputation: 1121306
You need to look up the call stack by using inspect.stack()
:
from inspect import stack
def where():
caller_frame = stack()[1]
return caller_frame[0].f_globals.get('__file__', None)
or even:
def where():
caller_frame = stack()[1]
return caller_frame[1]
Upvotes: 12
Reputation: 168596
You can use traceback.extract_stack
:
import traceback
def where():
return traceback.extract_stack()[-2][0]
Upvotes: 3