walknotes
walknotes

Reputation: 1050

Determine where a function was executed?

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

Answers (4)

TehTris
TehTris

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

Aya
Aya

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

Martijn Pieters
Martijn Pieters

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

Robᵩ
Robᵩ

Reputation: 168596

You can use traceback.extract_stack:

import traceback
def where():
    return traceback.extract_stack()[-2][0]

Upvotes: 3

Related Questions