views:

1728

answers:

2

Suppose myapp/foo.py contains:

def info(msg):
    caller_name = ????
    print '[%s] %s' % (caller_name, msg)

And myapp/bar.py contains:

import foo
foo.info('Hello') # => [myapp.foo] Hello

I want caller_name to be set to the __name__ attribute of the calling functions' module (which is 'myapp.foo') in this case. How can this be done?

+10  A: 

Check out the inspect module:

inspect.stack() will return the stack information.

Inside a function, inspect.stack()[1] will return your caller's stack. From there, you can get more information about the caller's function name, module, etc.

See the docs for details:

http://docs.python.org/library/inspect.html

Also, Doug Hellmann has a nice writeup of the inspect module in his PyMOTW series:

http://blog.doughellmann.com/2007/11/pymotw-inspect.html

EDIT: Here's some code which does what you want, I think:

def info(msg):
    frm = inspect.stack()[1]
    mod = inspect.getmodule(frm[0])
    print '[%s] %s' % (mod.__name__, msg)
ars
So how do you get the `__name__` attribute of this module using the `inspect` module? For example, how do I get back `myapp.foo` (not `myapp/foo.py`) in my above example? I already tried using the inspect module before posting at SO.
Sridhar Ratnakumar
Just updated the answer. Does that work on your end?
ars
Be aware that this will interact strangely with import hooks, won't work on ironpython, and may behave in surprising ways on jython. It's best if you can avoid magic like this.
Glyph
+1  A: 

I don't recommend do this, but you can accomplish your goal with the following method:

def caller_name():
    frame=inspect.currentframe()
    frame=frame.f_back.f_back
    code=frame.f_code
    return code.co_filename

Then update your existing method as follows:

def info(msg):
    caller = caller_name()
    print '[%s] %s' % (caller, msg)
Mark Roddy
Filename is not the same as `__name__`
Sridhar Ratnakumar