Find function name in function 
Author Message
 Find function name in function

Hi,

Is it possible to find the function name in that specific function?
I the following example I want to be able to find what name the user
used to call the function: XXX, yy, zz
Is that possible?

def XXX():
     #find function name XXX or yy
     pass
XXX()
yy=XXX
yy()
zz=XXX
zz()

Thank you,
Lale



Sat, 05 Nov 2005 22:04:46 GMT  
 Find function name in function


Quote:
> Is it possible to find the function name in that specific function?

In CPython, it is possible to get a handle on a function from within a
function and from that gets its *definition* name (the one in the def
statement), but you are asking about the names bound to the function
..

Quote:
> I the following example I want to be able to find what name the user
> used to call the function: XXX, yy, zz
> Is that possible?

I do not believe this is sanely possible.  (Insanely would be getting
the code and line number of the calling context, decompiling the code
and using the linenum to find the call and from that the calling name,
if there is one.

Quote:
> def XXX():
>      #find function name XXX or yy
>      pass
> XXX()
> yy=XXX
> yy()
> zz=XXX
> zz()

You left out the possibility of calling a function without a name or
without it even having any bound names left.

def f(): print 'hi'

fl = [f]
del f
fl[0]()
# prints
hi

Terry J. Reedy



Sat, 05 Nov 2005 23:17:52 GMT  
 Find function name in function
Hi.


Quote:
> Is it possible to find the function name in that specific function?
> I the following example I want to be able to find what name the user
> used to call the function: XXX, yy, zz
> Is that possible?

Not exactly. You can find the name of the function, 'XXX', but not the name
of the referencer, 'yy' or 'zz', with this:

# credit Alex Martelli, "Python Cookbook" p. 440
def whoami():
    "returns name of calling function"
    import sys
    return sys._getframe(1).f_code.co_name

def XXX():
    print whoami()

XXX()
yy=XXX
yy()
zz=XXX
zz()

This outputs:
XXX
XXX
XXX

Or, you can get the source line where this function is called:

def howamicalled():
    "returns source line where calling function is called"
    import inspect
    return inspect.stack()[2][-2][0].strip()

def XXX():
    print howamicalled()

XXX()
yy=XXX
yy()
zz=XXX
zz()

which outputs:
XXX()
yy()
zz()

This seems useful until you do something like the following:

print "%s %s"%(yy(), zz())

Now, this will output:

print "%s %s"%(yy(), zz())
print "%s %s"%(yy(), zz())

At which point I do not think you can reliably isolate which function was
the one being called. For instance, we can define a new function

def foo():
    pass

and

print "%s %s"%(yy(), foo())

will output:

print "%s %s"%(yy(), foo())

But, which function is a referencer to XXX?

So, the answer to your question is, "No, I don't think so"

Hope this helped,
Sean



Sat, 05 Nov 2005 23:12:22 GMT  
 Find function name in function
Ilariu Raducan schreef op dinsdag 20 mei om 16:08:10 +0000:

Quote:
> Is it possible to find the function name in that specific function?

It is, but why do you need it?
Using tracebacks you can do it...

It's quite difficult, but if you want I can find it out for you.

I think I did it once...

yours,
Gerrit.

--
208. If he was a freed man, he shall pay one-third of a mina.
        -- Hammurabi, Code of Law
--
Asperger Syndroom - een persoonlijke benadering:
        http://people.nl.linux.org/~gerrit/
Het zijn tijden om je zelf met politiek te bemoeien:
        http://www.sp.nl/



Sat, 05 Nov 2005 23:58:18 GMT  
 Find function name in function
Here's something that gets you a little bit closer to what you're looking
for, however, you will notice that it does not resolve the issue presented
in my previous posting. I.e., if you have two (or more) aliases to a
function and you call them in the same line of code, WhoMightIBe() cannot
determine which of the aliases was used, it can only tell you that the list
of possible aliases.

def WhoMightIBe():
    "returns name and/or possible alias' of called calling function"
    import inspect, re
    stack = inspect.stack()
    # get name of function as listed in def statement
    defname = eval(stack[1][-3])
    # get the source line where function is called
    srcline = stack[2][-2][0].strip()
    # extract function names from source line (robust? ...doubtful)
    pattern = re.compile(r'[a-z,A-Z,0-9,_]+\(')
    matches = [txt.replace('(','') for txt in pattern.findall(srcline)]
    # see which function name(s) alias(es) our target function
    possibles = [funcname for funcname in matches if eval(funcname) is
defname]
    return possibles

def XXX():
    print WhoMightIBe()

XXX()
yy=XXX
a= yy()
zz=XXX
zz()

print "%s %s"%(yy(), zz())

#outputs:
['XXX']
['yy']
['zz']
['yy', 'zz']
['yy', 'zz']
None None



Sun, 06 Nov 2005 01:21:19 GMT  
 Find function name in function
Okay, here you go...This function will identify the called functions name by
it's proper name or by it's alias, however it's being called. It grabs the
frame where the function was called, gets the associated code object and
last instruction index, disassembles the code object, isolates the
instruction, and slices out the function name. I don't know if this is
robust, dangerous, or whatever, but it does what you're asking for.

def whoami2():
    "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()

    # restore stdout
    sys.stdout = oldout

    fd = open('log')

    # retrieve current byte code line
    current = [line for line in fd.readlines() if line.startswith('-->')][0]
    fd.close()

    # isolate function name
    funcname = current.split()[-1][1:-1]
    return funcname

def XXX():
    print whoami2()

XXX()
yy=XXX
a= yy()
zz=XXX
zz()

print "%s %s"%(yy(), zz())

# OUTPUT
XXX
yy
zz
yy
zz
None None



Sun, 06 Nov 2005 03:15:42 GMT  
 Find function name in function
As a bonus, this even works for methods:

# I've changed the name of whoami2 to whoaminow
class c:
    def foo(self):
        print whoaminow()

inst = c()
inst.foo()
bar = inst.foo
bar()

#OUTPUTS
foo
bar



Sun, 06 Nov 2005 03:53:41 GMT  
 Find function name in function


Quote:
> Okay, here you go...This function will identify the called functions
name by
> it's proper name or by it's alias, however it's being called. It
grabs the
> frame where the function was called, gets the associated code object
and
> last instruction index, disassembles the code object, isolates the
> instruction, and slices out the function name. I don't know if this
is
> robust, dangerous, or whatever, but it does what you're asking for.

As I pointed out in my first response to the OP, functions do not
necessarily have a 'called-by' name.

# revised be removing blank lines so cut and paste works
def whoami2():
    "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()
    # restore stdout
    sys.stdout = oldout
    fd = open('log')
    # retrieve current byte code line
    current = [line for line in fd.readlines() if
line.startswith('-->')][0]
    fd.close()
    # isolate function name
    funcname = current.split()[-1][1:-1]
    return funcname

def XXX():
    print whoami2()

Quote:
>>> XXX()

XXX # verifies copy ok
Quote:
>>> fl=[XXX]
>>> fl[0]()

Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "<stdin>", line 2, in XXX
  File "<stdin>", line 18, in whoami2
IndexError: list index out of range

I suppose you could wrap that line in try:except: and return '' in
this case.  But the user had better be prepared for a null name.

Terry J. Reedy



Sun, 06 Nov 2005 06:39:11 GMT  
 Find function name in function

Quote:

> >>> XXX()
> XXX # verifies copy ok
> >>> fl=[XXX]
> >>> fl[0]()
> Traceback (most recent call last):
>   File "<stdin>", line 1, in ?
>   File "<stdin>", line 2, in XXX
>   File "<stdin>", line 18, in whoami2
> IndexError: list index out of range

> I suppose you could wrap that line in try:except: and return '' in
> this case.  But the user had better be prepared for a null name.

Oddly enough, I don't get that error, however I do not the name I'm looking
for either, so for the time being I've added an else clause to the for loop.
Now, if I don't find the name, I return None so the user can tell that the
name was not found by checking for this condition.

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:
        line = None
    fd.close()
    # isolate function name
    if line:
        funcname = line.split()[-1][1:-1]
    else:
        funcname = None
    return funcname

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

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

#outputs
None



Sun, 06 Nov 2005 08:33:54 GMT  
 Find function name in function
Unfortunately, this code fails for any function with more than zero
arguments (which is most of them!). So... I tried...no luck...moving on...


Sun, 06 Nov 2005 09:15:55 GMT  
 Find function name in function
Sean Ross schreef op dinsdag 20 mei om 21:29:01 +0000:

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

>     # restore stdout
>     sys.stdout = oldout

I think backuping sys.stdout is not necessary, as sys.__stdout__
exists for that goal.

yours,
Gerrit.

--
117. If any one fail to meet a claim for debt, and sell himself, his
wife, his son, and daughter for money or give them away to forced labor:
they shall work for three years in the house of the man who bought them,
or the proprietor, and in the fourth year they shall be set free.
        -- Hammurabi, Code of Law
--
Asperger Syndroom - een persoonlijke benadering:
        http://people.nl.linux.org/~gerrit/
Het zijn tijden om je zelf met politiek te bemoeien:
        http://www.sp.nl/



Sun, 06 Nov 2005 17:34:27 GMT  
 Find function name in function
Okay, thanks. I've never needed to redirect stdout before, so I didn't know.
I also didn't know about the dis module before this little failed
experiment, so I've managed to get a few things out of this.


Quote:
> Sean Ross schreef op dinsdag 20 mei om 21:29:01 +0000:
> >     # redirect ouput of disassemble (stdout)
> >     oldout = sys.stdout
> >     sys.stdout = open('log','w')
> >     dis.disassemble(code, lasti)
> >     sys.stdout.close()

> >     # restore stdout
> >     sys.stdout = oldout

> I think backuping sys.stdout is not necessary, as sys.__stdout__
> exists for that goal.

> yours,
> Gerrit.

> --
> 117. If any one fail to meet a claim for debt, and sell himself, his
> wife, his son, and daughter for money or give them away to forced labor:
> they shall work for three years in the house of the man who bought them,
> or the proprietor, and in the fourth year they shall be set free.
>         -- Hammurabi, Code of Law
> --
> Asperger Syndroom - een persoonlijke benadering:
> http://people.nl.linux.org/~gerrit/
> Het zijn tijden om je zelf met politiek te bemoeien:
> http://www.sp.nl/



Sun, 06 Nov 2005 22:27:56 GMT  
 Find function name in function
Quoth Gerrit Holl:
  [...]

Quote:
> I think backuping sys.stdout is not necessary, as sys.__stdout__
> exists for that goal.

But what if the caller of this code has itself changed sys.stdout
temporarily for some reason?  Backup and restore is a good idea.

(Though obviously it would be best for this application if dis
weren't hard-coded to use sys.stdout.)

--
Steven Taschuk                                7\ 7'Z {&~         .

                                            (__/ )_             1^1`



Mon, 07 Nov 2005 01:55:21 GMT  
 Find function name in function

Quote:

> I think backuping sys.stdout is not necessary, as sys.__stdout__
> exists for that goal.

If this is intended to act as a standalone script, you of course have a
point.  If it's a library function, though, sys.stdout may have already
been overridden at some point and you may want to be safe.

--

 __ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
/  \ Have you ever loved somebody / Who didn't know
\__/  Zhane



Mon, 07 Nov 2005 02:33:31 GMT  
 
 [ 14 post ] 

 Relevant Pages 

1. How to find out name of calling function from called function

2. Name valid outside function, but error name inside function

3. VISA Find function to VISA Resource Name

4. Trouble using variables for function names in function declarations

5. conflict class function name with ordinary function

6. Function parameter names within a function

7. Name of function within the function?

8. Can't find function name.

9. Trouble using variables for function names in function declarations

10. Retrieving the name of a function from within the function

11. Function names and "filter" function

12. Call Library Function - Function not found in library

 

 
Powered by phpBB® Forum Software