How to turn a variable name into a string?

S

Stewart Midwinter

I'd like to do something like the following:

a = 1; b = 2; c = None
mylist = [a, b, c]
for my in mylist:
if my is None:
print 'you have a problem with %s' % my #this line is problematic

What I want to see in the output is:
How do I convert a variable name into a string?

thanks!
 
P

Peter Hansen

Stewart said:
I'd like to do something like the following:

a = 1; b = 2; c = None
mylist = [a, b, c]
for my in mylist:
if my is None:
print 'you have a problem with %s' % my #this line is problematic

What I want to see in the output is:
How do I convert a variable name into a string?

You cannot. In the above example, when you hit
the None item in the list, there is only one None
object in existence, and three different names
"bound" to it: c, my, and the third spot in the
list. (Think of this "bound" thing as being like
strings attaching a variety of names to the item
itself.)

Given the object "None" then, how can Python know
which of the names you intended? More to the
point, by the time you've finished creating the
list mylist, the connection to "c" is long gone.
It is exactly as though you had typed this instead:
mylist = [1, 2, None]

There are doubtless other ways to accomplish what
you are really trying to do (display some sort of
information for debugging purposes?), but with a
contrived example it's a little hard to pick the
best...

By the way, this sort of thing should be well
covered by the FAQ entries, if you read them.
See, for example,
http://www.python.org/doc/faq/programming.html#how-can-my-code-discover-the-name-of-an-object

-Peter
 
L

Lonnie Princehouse

Any given Python object may be bound to multiple names or none at all,
so trying to find the symbol(s) which reference an object is sort of
quixotic.

In fact, you've got None referenced by both "my" and "c" in this
example, and in a more complicated program None will be referenced by
dozens symbols because it's unique [e.g. (a == None, b == None)
necessitates (a is b) == True]

You could try using "is" to match it with something in the namespace,
though. This might do what you want.

def names(thing):
return [name for name,ref in globals().iteritems() if ref is thing]

a = 1; b = 2; c = None

mylist = [a,b,c]
for my in mylist:
if my is None:
print 'you have a problem with %s' % names(my)


-------------

Although it would be much simpler to rewrite your code like this:

a = 1; b = 2; c = None

mylist = ['a','b','c']
for my_name in mylist:
my = eval(my_name)
if my is None:
print 'you have a problem with %s' % my_name
 
P

Paolo G. Cantore

Hi Stewart,

what about the other way, string -> var and not var -> string?

My suggestion:
mylist = ["a", "b", "c"]
for my in mylist:
if locals()[my] == None:
print "you have a problem with %s" % my

Paolo

Stewart said:
I'd like to do something like the following:

a = 1; b = 2; c = None
mylist = [a, b, c]
for my in mylist:
if my is None:
print 'you have a problem with %s' % my #this line is problematic



What I want to see in the output is:


How do I convert a variable name into a string?

thanks!
 
S

Scott David Daniels

Stewart said:
I'd like to do something like the following:

a = 1; b = 2; c = None
mylist = [a, b, c]
for my in mylist:
if my is None:
print 'you have a problem with %s' % my #this line is problematicWhat I want to see in the output is:
How do I convert a variable name into a string?

I think you actually want the opposite:

a = 1; b = 2; c = None
mylist = ['a', 'b', 'c']
for my in mylist:
if globals()[my] is None:
print 'you have a problem with %s' % my
 
S

stewart.midwinter

lots of good answers there, and quickly, too!

I can see that I need to explain a bit further what I'm up to.

I have a number of variables (environmental variables, actually), most
of which will have a value. But some may not have been found by
os.environ.get(), so I set those to None. Now, if any of them are None,
the app cannot proceed, so I want to test for this and warn the user.
I could do something like this (actually, there are more than 3 vars):
a = "c:\\programs"
b = "d:\\data"
c = None (result of an assignment after the os.environ.get() returned
a KeyError).
if (a is None) or (b is None) or (c is None):
#do something here
print 'you are missing some env vars'

But, that seemed clumsy to me, so I wanted to do something more
pythonic, hence my previous post. So, any suggestions?

thanks!
S
 
R

Rodney Maxwell

c = None (result of an assignment after the os.environ.get()
returned a KeyError).

Why not trap the KeyError?
 
?

=?ISO-8859-1?Q?Andr=E9_Roberge?=

lots of good answers there, and quickly, too!

I can see that I need to explain a bit further what I'm up to.

I have a number of variables (environmental variables, actually), most
of which will have a value. But some may not have been found by
os.environ.get(), so I set those to None. Now, if any of them are None,
the app cannot proceed, so I want to test for this and warn the user.
I could do something like this (actually, there are more than 3 vars):
a = "c:\\programs"
b = "d:\\data"
c = None (result of an assignment after the os.environ.get() returned
a KeyError).
if (a is None) or (b is None) or (c is None):
#do something here
print 'you are missing some env vars'

But, that seemed clumsy to me, so I wanted to do something more
pythonic, hence my previous post. So, any suggestions?
Why not build a list of problematic variables as you assign them?
In this case, you would have
problem_list = [c]

if problem_list != []:
# do something here

etc.

André
 
L

Lonnie Princehouse

Perhaps try something like this?

variables = ['a', 'b', 'c']

defaults = {
'a': 'c:\\programs',
'b': 'd:\\data',
# etc
}

try:
settings = dict([(v, os.environ.get(v, defaults[v])) for v in
variables])
except KeyError, k:
# handle missing variable
print "you have a problem with %s" % k.args[0]

# Now if you really must have these as independent variables
globals().update(settings)
 
B

Bengt Richter

lots of good answers there, and quickly, too!

I can see that I need to explain a bit further what I'm up to.

I have a number of variables (environmental variables, actually), most
of which will have a value. But some may not have been found by
os.environ.get(), so I set those to None. Now, if any of them are None,
the app cannot proceed, so I want to test for this and warn the user.
I could do something like this (actually, there are more than 3 vars):
a = "c:\\programs"
b = "d:\\data"
c = None (result of an assignment after the os.environ.get() returned
a KeyError).
if (a is None) or (b is None) or (c is None):
#do something here
print 'you are missing some env vars'

But, that seemed clumsy to me, so I wanted to do something more
pythonic, hence my previous post. So, any suggestions?
If you require a specific set of environment variables to be defined,
why don't you create an object that loads them and validates itself
in the process? E.g.,
... def __init__(self, required=''):
... for name in required.split():
... self[name] = os.environ.get(name)
... if None in self.values():
... raise ValueError, 'You are missing some env vars: %r' % [k for k,v in self.items() if v is None]
... __getattr__ = dict.__getitem__
... {'TMP': 'v:\\TEMP', 'OS': 'Windows_NT'}

The __getattr__ assignment lets you access the keys as attributes if you want:
'v:\\TEMP'

If you try to init with some unknown env variable name, it complains:
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 6, in __init__
ValueError: You are missing some env vars: ['unknown']

If you have spaces in your environment names (possible?) that would be nasty and
you would have to change the "required" __init__ parameter to split on something other than spaces.
You could arrange for case-insensitivity if you liked. And if you really wanted
to have local or global bindings for your env names, you could easily do that too,
but e.g., myenv.XXX seems like a readable way to group things together.

Regards,
Bengt Richter
 
T

Terry Reedy

In fact, you've got None referenced by both "my" and "c" in this
example, and in a more complicated program None will be referenced by
dozens symbols because it's unique [e.g. (a == None, b == None)
necessitates (a is b) == True]

Even worse: freshly started 2.2 interpreter:216

TJR
 
S

Scott David Daniels

How about this:

try:
mumble = os.environ['TMP']
babble = os.environ['Path']
frobotz = os.environ['NotThere']
jangle = int(os.environ['WEIGHT'])
...
except KeyError, e:
print 'Mising env var %r. Fix it and try again' % e.args
raise SystemExit

--Scott David Daniels
(e-mail address removed)
 

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
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top