ActiveState Code

Recipe 52315: Obtaining the name of a function/method


How to obtain the name of a method or a function from within the running method/function.

Acknowledgement: the solution to this problem is given by Christian Tismer (tismer@tismer.com; Mission Impossible 5oftware)

Python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# obtaining the name of a function/method
# Christian Tismer
# March 2001

# the following function might be implemented in the
# sys module, when generators are introduced.
# For now, let's emulate it. The way is quite inefficient
# since it uses an exception, but it works.

import sys

def _getframe(level=0):
    try:
        1/0
    except:
        import sys
        tb = sys.exc_info()[-1]
    frame = tb.tb_frame
    while level >= 0:
        frame = frame.f_back
        level = level - 1
    return frame

sys._getframe = _getframe
del _getframe

# we now assume that we have sys._getframe

def funcname():
    return sys._getframe(1).f_code.co_name

class Log:

    def __init__(self):
        self.previous = None

    def methodA(self):
        self.previous = funcname()

    def methodB(self):
        self.previous = funcname()

myinstance = Log()
myinstance.methodA()
print myinstance.previous
myinstance.methodB()
print myinstance.previous

printout="""
methodA
methodB
"""
# that's all folks

Comments

  1. 1. At 2:31 p.m. on 12 apr 2001, Jeremy Hylton said:

    Python 2.1 sys._getframe(). The getframe function described in this recipe is available as a builtin function in Python 2.1. sys._getframe() returns the current frame object.

  2. 2. At 9:29 a.m. on 31 jan 2002, Tino Lange said:

    Determining Python Version on import. Hi!

    Because sys._getframe() is available for Python > 2.1 I suggest to change the Code like this - so you make sure that noone overwrites the fast Python >= 2.1 -implementation:

    if sys.version[:3] < '2.1': # sys.version_info is also not available for early pythons....
        #print 'loading emulated sys._getframe() for Python < 2.1'
        def _getframe(level=0):
            try:
                1/0
            except:
                import sys
                tb = sys.exc_info()[-1]
            frame = tb.tb_frame
            while level >= 0:
                frame = frame.f_back
                level = level - 1
            return frame
    
        sys._getframe = _getframe
        del _getframe
    
  3. 3. At 2:26 p.m. on 12 apr 2002, Sean True said:

    A mild flaw in this implementation. The reference to tb needs to be eradicated (well known Python lore). I had a case of the reference causing a refcount bump on an object (a lock object) two levels up from the call to getframe(). The increased refcount caused the lock object to persist after it was deleted, which was not expected (or appreciated).

    Not a problem with newer Python with native getframe(), I hope.

    def getframe(level=0):
         try:
             1/0
         except:
             import sys
             tb = sys.exc_info()[-1]
         frame = tb.tb_frame
         # The next line seems important.
         tb = None
         while level >= 0:
             frame = frame.f_back
             level = level - 1
         return frame
    

    <p>

    -- Sean True

    Webreply, Inc.

  4. 4. At 11:43 a.m. on 1 nov 2002, Peter Hansen said:

    Slightly better approach? Perhaps better than checking the version is simply to test for the existence of the function:

    if not hasattr(sys, '_getframe'):
       # do the rest here as before
    

    It's generally better to test for capabilities rather than versions.

Sign in to comment