What you've asked for can't be done (nicely -- there are ways of doing it but they are nasty hacks). BUT: you don't really want to do that. Think at a higher level: you want an easy way to modify a function to log that it has started. Changing the source code of the function isn't a good way do to that -- after all, the logging has nothing to do with what the function is doing! Instead, you want to modify the function ex post facto.
def startLog( func ):
def loggedFunc( *args, **kwargs ):
print( "starting {0} with {1}".format( func.__name__, args[ 0 ] ) )
return func( *args, **kwargs )
return loggedFunc
@startLog
def theFunc( ):
print( "running theFunc" )
theFunc( )
# starting theFunc
# running theFunc
This is an example of a Python decorator: it transforms a function at define-time into another one. It's syntactic sugar for:
def theFunc( ):
print( "running theFunc" )
theFunc = startLog( theFunc )
In other words, you are taking the function object itself (remember -- functions are objects too, you can pass them around, modify them, look at their attributes, etc!) and redefining it. Looking at the source code, we see that startLog
defines a new function (loggedFunc
), which first prints a log trace and then runs the original function, passing through its arguments. Applying the decorator replaces theFunc
with loggedFunc
, so that the function bound to the name theFunc
now logs itself!
Does that make sense? I'm happy to explain it in more detail.
Edit
As has been pointed out, this doesn't specifically answer your question; if you need any more functionality than this then use the logging
module which does everything you'll ever need and then some. Walking the stack is just icky, as well as fragile, though =p.