Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Getting the argument names passed to a function ?

0 views
Skip to first unread message

Andreas Jung

unread,
Apr 4, 2000, 3:00:00 AM4/4/00
to pytho...@python.org
def myfunc(arg1,arg2):
...


a=1;b=2
myfunc(a,b)

Is it possible to get the name of variables that were
used as arguments to call myfunc(). myfunc() should be
able to determine the names 'a' and 'b'. Don't ask
me why I need this - it's for a worse Python hack :-)

Cheers,
Andreas

Fredrik Lundh

unread,
Apr 4, 2000, 3:00:00 AM4/4/00
to

short answer: no

longer answer: maybe, using the incredibly clever and
totally evil bytecodehacks stuff:

http://bytecodehacks.sourceforge.net

</F>

<!-- (the eff-bot guide to) the standard python library:
http://www.pythonware.com/people/fredrik/librarybook.htm
-->

Ivan Van Laningham

unread,
Apr 4, 2000, 3:00:00 AM4/4/00
to Python Mailing List
Hi All

Mark Jackson wrote:
>

[wholesale snippery]

> But you forget about:
>
> >>> a=1
> >>> b=a
> >>> arghack(a)
> 'a'
> >>> arghack(b)
> 'a'
> >>>
>
> Your move. . . :-)
>
>

You guys are sick. And getting sicker. You need professional help.

<time-share-avatar-for-a-slew-of-minor-deities.--inquire within.>-ly
y'rs,
Ivan;-)
----------------------------------------------
Ivan Van Laningham
Callware Technologies, Inc.
http://www.pauahtun.org and
http://www.foretec.com/python/workshops/1998-11/proceedings.html
Army Signal Corps: Cu Chi, Class of '70
Author: Teach Yourself Python in 24 Hours


Quinn Dunkan

unread,
Apr 5, 2000, 3:00:00 AM4/5/00
to
On Tue, 04 Apr 2000 21:08:55 GMT, Fredrik Lundh <eff...@telia.com> wrote:
>Andreas Jung <aj...@sz-sb.de> wrote:
>>
>> def myfunc(arg1,arg2):
>> ...
>>
>>
>> a=1;b=2
>> myfunc(a,b)
>>
>> Is it possible to get the name of variables that were
>> used as arguments to call myfunc(). myfunc() should be
>> able to determine the names 'a' and 'b'. Don't ask
>> me why I need this - it's for a worse Python hack :-)
>
>short answer: no
>
>longer answer: maybe, using the incredibly clever and
>totally evil bytecodehacks stuff:
>
> http://bytecodehacks.sourceforge.net

Hmm, could you say:

def arghack(arg):
for k, v in globals().items():
if arg is v:
return k
else:
return None

Seems to work ok...

Quinn Dunkan

unread,
Apr 5, 2000, 3:00:00 AM4/5/00
to
> > Hmm, could you say:
> >
> > def arghack(arg):
> > for k, v in globals().items():
> > if arg is v:
> > return k
> > else:
> > return None
> >
> > Seems to work ok...
> This only works if the argument passed in is a global. For example:
> >>> def hackSpoiler():
> ... a = 2
> ... print arghack(a)
> ...
> >>> hackSpoiler()
> None

Ok, Mr. Spoilsport :)

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

Mark Jackson

unread,
Apr 5, 2000, 3:00:00 AM4/5/00
to

But you forget about:

>>> a=1
>>> b=a
>>> arghack(a)
'a'
>>> arghack(b)
'a'
>>>

Your move. . . :-)

--
Mark Jackson - http://www.alumni.caltech.edu/~mjackson
An advertiser will happily make you feel bad about
yourself if that will make you buy, say, a Bic pen.
- George Meyer


Andreas Jung

unread,
Apr 5, 2000, 3:00:00 AM4/5/00
to Quinn Dunkan
> 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

That's the perfect solution I was looking for :-) Thanks !

Cheers,
Andreas


Quinn Dunkan

unread,
Apr 5, 2000, 3:00:00 AM4/5/00
to
On 5 Apr 2000 01:55:02 GMT, Mark Jackson <mjac...@wc.eso.mc.xerox.com> wrote:
>But you forget about:
>
>>>> a=1
>>>> b=a
>>>> arghack(a)
>'a'
>>>> arghack(b)
>'a'
>>>>
>
>Your move. . . :-)

Hmm. How about:

def arghack2(arg):
import sys


try:
1/0
except:
frame = sys.exc_info()[2].tb_frame

co = frame.f_back.f_code
c = map(ord, co.co_code)
c.reverse()
def getop(st=c):
try:
op = st.pop()
except IndexError:
return None, None
oparg = None
if op > 89:
oparg = st.pop() + st.pop() * 256
return op, oparg
while 1:
op, oparg = getop()
if op is None: break
if op == 127 and oparg == frame.f_back.f_lineno:
break
while 1:
op, oparg = getop()
if op is None: break
if (op == 101 or op == 116) and (
co.co_names[oparg] == frame.f_code.co_name):
break
op, oparg = getop()
if op == 101:
return co.co_names[oparg]
elif op == 124:
return co.co_varnames[oparg]
else:
return

Michael Hudson

unread,
Apr 5, 2000, 3:00:00 AM4/5/00
to
qu...@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

Michael Hudson

unread,
Apr 5, 2000, 3:00:00 AM4/5/00
to
qu...@zloty.ugcs.caltech.edu (Quinn Dunkan) writes:

> On 5 Apr 2000 01:55:02 GMT, Mark Jackson <mjac...@wc.eso.mc.xerox.com> wrote:
> >But you forget about:
> >
> >>>> a=1
> >>>> b=a
> >>>> arghack(a)
> >'a'
> >>>> arghack(b)
> >'a'
> >>>>
> >
> >Your move. . . :-)
>
> Hmm. How about:
>

[snip]

Wow.

Have you downloaded bytecodehacks yet?

Quinn Dunkan

unread,
Apr 5, 2000, 3:00:00 AM4/5/00
to
On 05 Apr 2000 12:42:48 +0100, Michael Hudson <mw...@cam.ac.uk> wrote:
>Have you downloaded bytecodehacks yet?

Yeah, I've looked at it. Nice work. But I fear if I actually used it I might
be tempted to do this sort of thing more often :)

0 new messages