Getting current variable name

P

pl

Hi all,
I followed the mails entitled 'How to turn a variable name into a
string?' in march 2005 posts as I have a similar problem.

I have to get some list variable names at some point in my program. So
I ended up looking into globals() to get them with a small function like
this:

#!/usr/bin/python

l1 = ['r', 'r', 't']
l2 = ['r', 't', 't']
l3 = ['t', 't', 't'] # Two equivalent lists but...
l4 = ['t', 't', 't'] # with different names

def nameofObj(obj):
# print locals()
globdict = globals()
var = globals().keys()
for i in var :
if globdict == obj:
print i


print '-'*20 ,'\n'
nameofObj(l1)

print '-'*20 ,'\n'
map(nameofObj, [l1, l2, l3, l4])

--------------------------------------------------------------------
If you try this, with 2 equivalent lists
(here l3 and l4 when using map) the function will return both
possibilities l3 and l4 which I understand.
So this solution is limitated to unique lists, unfortunately I do have
equivalent lists in my case...

The problem comes from the fact that locals() and globals() have
in common their values but not the keys which then can't be tested.

The only solution I see would be to link the list and its name (in
a dictionary for instance) but that does not sound elegant to me?
If you guys can help a newbie...

Thank you
--
------------------------------------------------------------------
| Patrick LADAM | |
| Laboratoire CSSB | THE BIG BANG THEORY: |
| UFR SMBH | |
| 74 rue Marcel Cachin | In the begining there was |
| 93017 Bobigny CEDEX | nothing at all. |
| >>> NEW e-mail: <<< | |
| (e-mail address removed)-paris13.fr | Then, it exploded... |
| Tel: 01 48 38 77 26 / 76 85 | |
| Fax: 01 48 38 77 77 | |
------------------------------------------------------------------
 
D

Daniel Dittmar

pl said:
I have to get some list variable names at some point in my program. So
I ended up looking into globals() to get them with a small function like
this: [...]
var = globals().keys()
for i in var :
if globdict == obj:
print i


Use 'is' instead of '=='. This will return true if the arguments are the
same object:
>>> l1 = [1, 2, 3]
>>> l2 = [1, 2, 3]
>>> l1 == l2 True
>>> l1 is l2
False

Daniel
 
S

Steven Bethard

pl said:
I followed the mails entitled 'How to turn a variable name into a
string?' in march 2005 posts as I have a similar problem.

I have to get some list variable names at some point in my program. So
I ended up looking into globals() to get them with a small function like
this:

#!/usr/bin/python

l1 = ['r', 'r', 't']
l2 = ['r', 't', 't']
l3 = ['t', 't', 't'] # Two equivalent lists but...
l4 = ['t', 't', 't'] # with different names

def nameofObj(obj):
# print locals()
globdict = globals()
var = globals().keys()
for i in var :
if globdict == obj:
print i


print '-'*20 ,'\n'
nameofObj(l1)

print '-'*20 ,'\n'
map(nameofObj, [l1, l2, l3, l4])


What is the problem you're trying to solve here? Looking up the names
of an object is not usually something you want to do. If you provide a
little more detail on your use case, we might be able to help you
refactor this code.

STeVe
 
R

Ron

pl said:
Hi all,
I followed the mails entitled 'How to turn a variable name into a
string?' in march 2005 posts as I have a similar problem.

Use the locals() function instead of globals().

Thanks by the way, I was wondering how to do this also, your post, and
Daniel pointing out 'is', helped me work this out. There should be an
easier way that doesn't require stepping though the name list.

This doesn't use lists in the same way, but I think it answers your
question.

def getvinfo(vars, v):
"""
vars is locals()
v is [varable]
Use an one item list to pass single varables by reference.
"""
for n in vars.keys():
if vars[n] is v[0]:
return n, v[0], type(v[0])

a = 101
b = 2.3
c = True

print getvinfo(locals(), [a])
print getvinfo(locals(), )
print getvinfo(locals(), [c])
('a', 101, <type 'int'>)
('b', 2.2999999999999998, <type 'float'>)
('c', True, <type 'bool'>)


This could be useful for printing error messages and debugging info.

Ronald Adam
 
J

Jeff Shannon

Ron said:
def getvinfo(vars, v):
"""
vars is locals()
v is [varable]
Use an one item list to pass single varables by reference.
"""
for n in vars.keys():
if vars[n] is v[0]:
return n, v[0], type(v[0])

a = 101
b = 2.3
c = True

print getvinfo(locals(), [a])
print getvinfo(locals(), )
print getvinfo(locals(), [c])
('a', 101, <type 'int'>)
('b', 2.2999999999999998, <type 'float'>)
('c', True, <type 'bool'>)


Are you sure that you really need that single-element list?
.... for n in vars.keys():
.... if vars[n] is v:
.... return n, v, type(v)
....
Now, making that second parameter a list would enable you to do this
for multiple local names with a single call, but getvinfo() doesn't
try to do that...

Don't forget, in Python, all names are references. You only have to
be careful when you start re-binding names...

Jeff Shannon
 
L

Lonnie Princehouse

There should be an easier way that doesn't require stepping though
the name list.

Trying to find names bound to a particular object is a /very/ strange
thing to want to do in Python. If this is for anything more than
debugging diagnostics, it's probably better to use a dictionary
explicitly for your variables and not muck around with global or local
namespace.
 
R

Ron

Jeff said:
Are you sure that you really need that single-element list?

No I'm not sure, I thought I found a concdition where it made a
difference while playing with it, but I don't recall just what
circumstance it was?
Don't forget, in Python, all names are references. You only have to be
careful when you start re-binding names...

Since more than one name can bind to an object, this would be better.


def getvinfo( vars, v ):
names = []
for n in vars.keys():
if vars[n] is v:
names.append(n)
return names, v, type(v)

a = [2]
b = [2]
c = b

print getvinfo( locals(), a )
print getvinfo( locals(), b )
print getvinfo( locals(), c )
(['a'], [2], <type 'list'>)
 
S

Steve

All names have been removed to protect the guilty :)

In an earlier post, I read a piece of code:
l1 = [1, 2, 3]
l2 = [1, 2, 3]
l1 == l2
True

I immediately gave a double-take: 11 equals 12? What
gives? Can you re-bind literals in Python???
SyntaxError: can't assign to literal

And then it hit me. That wasn't eleven and twelve, the
variable names were lowercase L with the digits one and
two appended.

Imagine running a long piece of code on some test data
and finding an off-by-one bug which you think is on the
line "myvalue = something + l1". You change the eleven
to 12 and now the code works on your test data but not
for anything else.

If you have access to a syntax-aware editor, it will
help avoid such problems, but better to avoid them in
the first place. You might be reading code printed in
black and white on dead tree one day.

Lesson the first: remember that in many fonts, zero and
capital O are identical, as are lowercase L and 1 and
sometimes even uppercase I. Avoid using names which can
be easily confused for literals or for each other.

What are some of other people's favourite tips for
avoiding bugs in the first place, as opposed to finding
them once you know they are there?
 
P

Paul McGuire

This struck me also when I first saw this post. It reminded me of a
body of code I inherited at a former job, that I had to help untangle.
The code was filled with two key variables: t_1 and t_l. Printing out
the source in a Courier font made these two vars completely
indistinguishable, and it took a while to realize that there even were
two different vars. After globally replacing them with t_first and
t_last, things became a lot clearer!

-- Paul
 
A

Andrew Dalke

Steve said:
[an anecdote on distinguishing l1 and 11]
What are some of other people's favourite tips for
avoiding bugs in the first place, as opposed to finding
them once you know they are there?

There's a good book on this topic - Writing Solid Code.

Andrew
(e-mail address removed)
 
E

Eric Brunel

Steve said:
[an anecdote on distinguishing l1 and 11]
What are some of other people's favourite tips for
avoiding bugs in the first place, as opposed to finding
them once you know they are there?

There's a good book on this topic - Writing Solid Code.

And there's an excellent website showing what *not* to do:
http://mindprod.com/unmain.html

The OP's point is paragraph 11 in the "Camouflage" section.
 
R

Richie Hindle

[Steven]
If you have access to a syntax-aware editor, it will
help avoid such problems

Seconded. Here's my favourite real-world example of where the lack of
syntax colouring cost several man-days of work (though this couldn't
happen with modern C compilers):

extern void get_s(short* s);

void f()
{
int i; /* An integer to do something /*
short s; /* A short to do something */

get_s(&s);
/* Do something with s */
}
 
P

Paul McGuire

Here's another real world example, although it was in C:

char* ptr;
assert( ptr = malloc( memsize ); )

Of course, this worked when built in debug, but it took a while to
track down why it wasn't working in the release build (the assert()'s
were stripped out in the release builds, so ptr didn't allocate any
memory). Unfortunately, the runtime failure happened in an entirely
different part of the code, since ptr wasn't initialized to null, so
this particular routine just merrily stomped on whatever memory address
happened to initialize in ptr.

-- Paul
 
T

Thomas Bartkus

What are some of other people's favourite tips for
avoiding bugs in the first place, as opposed to finding
them once you know they are there?
Fonts with slashed zeros and serifs.

-Tom
 
G

Greg Ewing

Paul said:
The code was filled with two key variables: t_1 and t_l. Printing out
the source in a Courier font made these two vars completely
indistinguishable,

Are you sure it was Courier? I'm looking at it now
in Courier, and they are different, although very
similar.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,232
Messages
2,571,169
Members
47,803
Latest member
ShaunaSode

Latest Threads

Top