How to get the same functionality as C __FUNCTION__ in Python?

In C, I can put the printf log inside a function like this:

void xx_lock (int xx_flag) { printf ("%s: START with %d\n", __FUNCTION__, xx_flag); } 

so I can copy the same line where I need any function, and it displays the function name in the log. I want something like this in Python. But if I use

 __name__ 

it displays the name of the module, not the name of the function.

 def xxx_lock(xx_flag=0) sys.stdout.write("%s: START with %d\n" % (__name__, xx_flag)) 

Is there some simple construct that I can use in this example to show the name of a Python function? To make a conclusion as follows:

 xxx_lock: START with 1 

Edited: parameter added to the example.

+4
source share
4 answers

katrielalex above is correct that you should not try to do this "C way". Python has batteries, so why not use them?

  import logging, sys

 logging.basicConfig (format = "% (filename) s:% (funcName) s:% (message) s", level = logging.DEBUG, stream = sys.stderr)

 def testFunc ():
     logging.debug ("entering")

 testFunc ()
+7
source

What you requested cannot be done (beautifully - there are ways to do this, but they are nasty hacks). BUT: you really don't want to do this. Think at a higher level: you need an easy way to change the function for registration with which it started. Changing the source code of a function is not a good way to do this - after all, a log has nothing to do with what the function does! Instead, you want to change the ex post facto function.

 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 converts a function in time-time to another. This is syntactic sugar for:

 def theFunc( ): print( "running theFunc" ) theFunc = startLog( theFunc ) 

In other words, you take the function object yourself (remember - functions are also objects, you can transfer them, change them, view their attributes, etc.!) And redefine it. After looking at the source code, we see that startLog defines a new function ( loggedFunc ), which first prints the trace of the log, and then runs the original function, passing through its arguments. Using the decorator replaces theFunc with loggedFunc , so the function associated with theFunc is now written itself!

It makes sense? I am pleased to explain this in more detail.

Edit

As already noted, this does not specifically answer your question; if you need more functionality than in this case, use the logging module, which will do everything you ever need, and then some. Walking on the glass is simply not good, but also fragile, although = p.

+9
source
 import inspect inspect.getframeinfo(inspect.currentframe()).function 

This provides functionality that is most similar to C __FUNCTION__, but as katrielalex said, this is a hack. The decorator is the best solution in the end.

+2
source
 import inspect def function_with_line(depth=1): stack = inspect.stack() frame = stack[depth][0] code = frame.f_code return "%s:%i" % (code.co_name, frame.f_lineno) def foo(): print "Currently in %s" % function_with_line() 

I do not recommend using this from high-level code; insert it into the logger and increase the depth to get the name of the correct stack frame. Also, keep in mind that this information will not be available in all Python implementations. It can also be quite slow in some Python implementations; If logging efficiency is important to you, run the appropriate tests.

You are probably best off using logging , but if this is not an option for any reason (e.g. integration with another existing logging system), then how to do it.

+1
source

All Articles