Created
March 21, 2012 19:29
-
-
Save techtonik/2151727 to your computer and use it in GitHub Desktop.
Python - inspect - Get full caller name (package.module.function)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Public Domain, i.e. feel free to copy/paste | |
# Considered a hack in Python 2 | |
import inspect | |
def caller_name(skip=2): | |
"""Get a name of a caller in the format module.class.method | |
`skip` specifies how many levels of stack to skip while getting caller | |
name. skip=1 means "who calls me", skip=2 "who calls my caller" etc. | |
An empty string is returned if skipped levels exceed stack height | |
""" | |
stack = inspect.stack() | |
start = 0 + skip | |
if len(stack) < start + 1: | |
return '' | |
parentframe = stack[start][0] | |
name = [] | |
module = inspect.getmodule(parentframe) | |
# `modname` can be None when frame is executed directly in console | |
# TODO(techtonik): consider using __main__ | |
if module: | |
name.append(module.__name__) | |
# detect classname | |
if 'self' in parentframe.f_locals: | |
# I don't know any way to detect call from the object method | |
# XXX: there seems to be no way to detect static method call - it will | |
# be just a function call | |
name.append(parentframe.f_locals['self'].__class__.__name__) | |
codename = parentframe.f_code.co_name | |
if codename != '<module>': # top level usually | |
name.append( codename ) # function or a method | |
del parentframe | |
return ".".join(name) |
thanks!!!
Think you,it's very useful~
I've never used Python before, is this too hard to use?
Nice
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks very much! This is a very useful function!
I have made one minor change to line 14. I noticed that when I was using this function to set the name of a logger at many points in my program, things seemed to start running pretty slowly. After profiling, it looks like this is due to line 14 (i.e., the call to
inspect.stack
). Fortunately, a simplified function can be used instead, as shown below:While the simple
stack_
function is not a drop-in replacement forinspect.stack
, it provides all the functionality required forcaller_name
and is over 2000x faster.Here is a modified version of the code, including an additional function
_L
which can be used to return a logger named based on the current method/function context: