In C, I can put a log printf 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 in any function and it displays the function name in the log. I want something similar in Python. But if I use
__name__
the same way, it displays the module name, not the function name.
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 that example to show the Python function name? To produce output like this:
xxx_lock: START with 1
Edited: added the parameter to the example.
__class__ is an attribute on the object that refers to the class from which the object was created. a. __class__ # Output: <class 'int'> b. __class__ # Output: <class 'float'> After simple data types, let's now understand the type function and __class__ attribute with the help of a user-defined class, Human .
A module in Python is a file (ending in .py ) that contains a set of definitions (variables and functions) that you can use when they are imported. Modules are considered as objects, just as everything else is in Python.
Check with the built-in function dir() The built-in function dir() returns a list of names of attributes, methods, etc. of the object specified in the argument. You can get a list of names of built-in objects, such as built-in functions and constants, by passing the builtins module or __builtins__ to dir() .
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.
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.
katrielalex above is right that you should not attempt to do this the "C way". Python has batteries included, 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()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With