# 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) |
This comment has been minimized.
This comment has been minimized.
|
This comment has been minimized.
This comment has been minimized.
Very useful, thank you. |
This comment has been minimized.
This comment has been minimized.
Thanks! |
This comment has been minimized.
This comment has been minimized.
|
This comment has been minimized.
This comment has been minimized.
6 years later, but still want to say thanks! |
This comment has been minimized.
This comment has been minimized.
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 ...
>>> import sys
>>> import inspect
>>>
>>> def stack_(frame):
... framelist = []
... while frame:
... framelist.append(frame)
... frame = frame.f_back
... return framelist
...
>>> %timeit stack_(sys._getframe(1))
100000 loops, best of 3: 3.09 µs per loop
>>> %timeit inspect.stack()
100 loops, best of 3: 8.36 ms per loop While the simple Here is a modified version of the code, including an additional function # Public Domain, i.e. feel free to copy/paste
# Considered a hack in Python 2
import inspect
import logging
import sys
def _L(skip=0):
'''Shorthand to get logger for current function frame.'''
return logging.getLogger(caller_name(skip + 1))
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
"""
def stack_(frame):
framelist = []
while frame:
framelist.append(frame)
frame = frame.f_back
return framelist
stack = stack_(sys._getframe(1))
start = 0 + skip
if len(stack) < start + 1:
return ''
parentframe = stack[start]
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) |
This comment has been minimized.
This comment has been minimized.
thanks!!! |
This comment has been minimized.
This comment has been minimized.
Think you,it's very useful~ |
This comment has been minimized.
This is exactly why I was overjoyed when http://www.python.org/dev/peps/pep-3155/ appeared. Python 3.3+ only, though.
Otherwise the only sure way to figure out the class name I can think of would be using
parentframe.f_code.co_filename
andco_firstlineno
, then parsing the source file (if it's available) and seeing what classes where defined in which code lines.