Welcome, guest | Sign In | My Account | Store | Cart

whoaminow() can be used inside a function to determine, at the time it is called, the name under which that function has been invoked.

NOTE: This solution is extremely brittle and provides very limited utility, as it stands. However, it does serve to highlight an interesting avenue for introspection, namely, the dis module.

Python, 66 lines
 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
54
55
56
57
58
59
60
61
62
63
64
65
66
def whoaminow():
    "returns name of called calling function"
    import sys, dis

    # get frame where calling function is called
    frame = sys._getframe(2)

    # get code and next to last instruction from frame
    code = frame.f_code
    lasti = frame.f_lasti-3

    # redirect ouput of disassemble (stdout)
    oldout = sys.stdout
    sys.stdout = open('log','w')
    dis.disassemble(code, lasti)
    sys.stdout.close()
    sys.stdout = oldout  # restore stdout

    # retrieve current byte code line
    fd = open('log')
    for line in fd.xreadlines():
        if line.startswith('-->'):
            break
    else: # couldn't find name
        line = None
    fd.close()
    
    # isolate function name
    if line is not None:
        funcname = line.split()[-1][1:-1]
    else: 
        funcname = None
    return funcname





# some testing...        
def foo():
    me = whoaminow() 
    return me


bar = foo
baz = foo
print "%s %s %s"%(foo(), bar(), baz())


class c:
    def fro(self):
        return whoaminow()

inst = c()
bozz = inst.fro
print "%s %s"%(inst.fro(),bozz())

fl = [foo]
print fl[0]()

"""
OUTPUTS:
foo bar baz
fro bozz
None
"""

Alex Martelli's whoami() function (see http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66062) allows you determine the "defined" name of the currently running function from inside that function. By "defined" name, I mean the name given to the function in it's def statement, e.g.,

def foo(): pass

has "defined" name 'foo'.

So, if you use whoami() inside foo(), it will tell you that the currently running function is 'foo'. But, if you alias foo, like so:

bar = foo

and then call bar (e.g., bar()), whoami() will still tell you that the currently running function is 'foo'. And this is certainly true, however, on occasion, you may prefer that whoami()'s report would return 'bar' instead. whoaminow() provides this behaviour.

NOTE: This recipe does not yet work properly for the test case fl0, above. This will return None, so if you use whoaminow(), be prepared to handle this case.

WARNING: This recipe will fail for functions with more than zero paremeters!

1 comment

Yuri Ivanov 10 years, 9 months ago  # | flag

Looks like in line 22 you need to lstrip() the line from the log :

    if line.lstrip().startswith('-->'):
        break
Created by Sean Ross on Tue, 20 May 2003 (PSF)
Python recipes (4591)
Sean Ross's recipes (8)

Required Modules

Other Information and Tasks