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
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
-->
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
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...
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
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
That's the perfect solution I was looking for :-) Thanks !
Cheers,
Andreas
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
> 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
> 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?
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 :)