Getting the argument names passed to a function ?

Michael Hudson mwh21 at cam.ac.uk
Wed Apr 5 04:13:12 EDT 2000


quinn at riyal.ugcs.caltech.edu (Quinn Dunkan) writes:

> import sys
> def arghack(arg):
>     try:
>         1/0
>     except:
>         frame = sys.exc_info()[2].tb_frame.f_back
>     while frame:
>         for k, v in frame.f_locals.items():
>             if arg is v:
>                 return k
>         frame = frame.f_back
>     else:
>         return None

You don't need to scan back through the frames do you?  I mean the
argument has to be visible just one up for it to be passed to the
function...

Anyway, it says in my contract that I have to answer questions like
this - so we'd better have:

import sys
from bytecodehacks.code_editor import EditableCode
from bytecodehacks.ops import *

def argHack(var):
    try:
        raise TypeError
    except TypeError:
        frame = sys.exc_traceback.tb_frame.f_back
        code = EditableCode(frame.f_code)
        op = code.co_code[code.co_code.byte2op[frame.f_lasti] - 1]
        if op.__class__ is LOAD_FAST:
            return code.co_varnames[op.arg]
        elif op.__class__ in [LOAD_NAME,LOAD_GLOBAL]:
            return code.co_names[op.arg]
        else:
            return None

There are various problems with extending this to being "useful",
mainly to do with working out the layout of the stack.  Tedious.

It seems to work, though:

>>> x=1
>>> def test(s): return argHack(s), argHack(x)
... 
>>> test(1)
('s', 'x')


Cheers,
M.

-- 
well, take it from an old hand: the only reason it would be easier
to program in C is that you can't easily express complex  problems
in C, so you don't.                 -- Erik Naggum, comp.lang.lisp



More information about the Python-list mailing list