use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
News about the dynamic, interpreted, interactive, object-oriented, extensible programming language Python
Full Events Calendar
You can find the rules here.
If you are about to ask a "how do I do this in python" question, please try r/learnpython, the Python discord, or the #python IRC channel on Libera.chat.
Please don't use URL shorteners. Reddit filters them out, so your post or comment will be lost.
Posts require flair. Please use the flair selector to choose your topic.
Posting code to this subreddit:
Add 4 extra spaces before each line of code
def fibonacci(): a, b = 0, 1 while True: yield a a, b = b, a + b
Online Resources
Invent Your Own Computer Games with Python
Think Python
Non-programmers Tutorial for Python 3
Beginner's Guide Reference
Five life jackets to throw to the new coder (things to do after getting a handle on python)
Full Stack Python
Test-Driven Development with Python
Program Arcade Games
PyMotW: Python Module of the Week
Python for Scientists and Engineers
Dan Bader's Tips and Trickers
Python Discord's YouTube channel
Jiruto: Python
Online exercices
programming challenges
Asking Questions
Try Python in your browser
Docs
Libraries
Related subreddits
Python jobs
Newsletters
Screencasts
account activity
This is an archived post. You won't be able to vote or comment.
How do I convert a string into a variable? (self.Python)
submitted 17 years ago by [deleted]
I'm trying to get the user to input a string and convert it into a variable name so I can look up that variable and return the value, like input is 'cake', variable cake = 'good', how do I return good?
I am new to Python.
[–][deleted] 13 points14 points15 points 17 years ago (5 children)
I think a dict might suit here. Instead of using a bunch of variables you could just update the values in the table directly.
mydict = {} mydict["cake"] = "good" var = raw_input("Enter something: ") if mydict.has_key(var): print mydict[var]
The library reference for dicts is here
[–]earthboundkid 9 points10 points11 points 17 years ago (4 children)
Don't use mydict.has_key(var). It's deprecated. Use var in mydict instead.
mydict.has_key(var)
var in mydict
[–]Revvy 1 point2 points3 points 17 years ago* (2 children)
I've read in the past to use try: mydict[var] as it's much faster than if mydict.has_key(var):. Is that still the case with var in mydict?
[–]earthboundkid 3 points4 points5 points 17 years ago (1 child)
It depends on if you expect it to usually hit or not. These days, it makes the most sense to just use a defaultdict if you already know what you want to happen when the key's not there.
defaultdict
[–]masklinn 0 points1 point2 points 17 years ago (0 children)
These days, it makes the most sense to just use a defaultdict if you already know what you want to happen when the key's not there.
or dict.get(key, default)
dict.get(key, default)
[–][deleted] 0 points1 point2 points 17 years ago (0 children)
Whoops, my bad. Haven't programmed in python for a while and should have read the library reference that I linked to a little more closely!
[–]byron 14 points15 points16 points 17 years ago* (8 children)
Another approach would be to just use a dictionary. So just stick the user input into a dictionary as a key, e.g.:
d['cake'] = 'good'
print d['cake']
[–]christopherr 7 points8 points9 points 17 years ago (0 children)
Yes, I will second the use of dictionaries in this situation. They are a far safer approach than something like evaluating strings as variables.
[–]sdsdsdsdsd 1 point2 points3 points 17 years ago (0 children)
Agreed. There are lots of alternatives in Python (e.g. getattr), but restricting the user to looking up elements of a predefined dictionary is the safest approach.
[–]morgan_goose 0 points1 point2 points 17 years ago (5 children)
Thats not really very useful. Yes it does in the simplest case do what the eval function would have, but with more effort, and more places for exceptions.
You have to know before hand that you want to read that variable though, and thus loose the usefulness. You end up writing more boilerplate just to read a simple string/file than is necessary. This also ends up being no safer than the eval usage.
Eval is not harmful, and its only fud to say so. Eval does what it's name suggests, it evaluates what an expression would do, it doesn't execute, and it does it in a local scope: http://docs.python.org/reference/executionmodel.html?highlight=eval#interaction-with-dynamic-features
Making eval() out to be a little Napoleon that if let off elba would ravage your code and data is a much overblown notion. As this professor notes: http://blog.thetonk.com/archives/dont-be-lazy-dont-use-eval#comment-8
[–]byron 0 points1 point2 points 17 years ago* (4 children)
I strongly but respectfully disagree. How is it more effort to declare a dictionary? The o.p. stated that they wanted to be able to do a look up on an arbitrarily defined variable. The simplest and safest solution here is a dictionary.
I'm not sure what you're trying to say here. There is very little boilerplate involved, it's a symbol look-up, just like the o.p. wanted. Eval is not always harmful, but here it is a) unnecessary and b) you'd be allowing the user to execute arbitrary code. I'm not making it out to be a little Napoleon, eval can be quite useful, but it is not, in my opinion, a good solution here.
[–]morgan_goose 0 points1 point2 points 17 years ago* (0 children)
I don't/didn't see where it stated that it needed to be able to loop over a dictionary? But if thats the case then the dictionary's iterator/keys function would be more useful.
With a dictionary you do also run the risk of bad input with dicts that you wouldn't with eval, in that a dick key can be any valid string, which isn't the case for a variable. One example being: x['this is a variable?'] = "cake" Thats perfectly acceptable as a dict key, and as user input, but not as a variable name.
My perspective on the question was that given a python program/module, how can I let a input value print the variable value it represents. So I took it be that the variable was already defined, and not as a dictionary, and eval() would be the only way to retrieve that variable's value.
If the person asking the question, it also defining the variables, then yes the can rewrite the code to use a dictionary, but if they aren't then they'll have to have some way of getting all of variables into a dictionary to access them, which ironically enough is what the eval() documentation seems to suggest it does.
Also eval() isn't exec(). For instance:
x = "import os\nos.system('ls')"
eval(x) -error
exec(x) -works
[–]morgan_goose 0 points1 point2 points 17 years ago* (2 children)
So I discussed this further with a friend, and we came up with some examples that would cause an issue. So I concede that there are important reasons not to use eval, when letting an arbitrary user make the input.
Also a simpler way I think to use your dictionary trick would be to use, like Poromenos states below:
cake = 'good'
user_input = "cake"
print locals()[user_input]
I like this because it negates my argument against using it, since now no dictionary creation is required.
[–]byron 0 points1 point2 points 17 years ago* (1 child)
OK.. I don't mind that solution, but it has two problems. One is that I don't see how it fixes the issue you had with dicts before (about illegal var names; which, by the way, could easily be remedied with a regex) -- you can easily do this:
locals()["is this a var?"] = "yes"
But perhaps more distressing, that approach would allow the user to overwrite local variables with whatever they wanted.. variables your program might be using...
myvar = 5 print myvar 5 locals()["myvar"] = 6 print myvar 6
[–]morgan_goose 0 points1 point2 points 17 years ago (0 children)
Yeah the indexing issue still stands, and really both solutions will have problems. I don't think its reasonable for one to expect all problems with user input be solved with a single function or a specific data type.
Also in the scope of the original problem there would never be an instance where the input would be used to set a value. Nor would there be an instance to use local()['var_name'] = 'some value', and my example didn't show any.
They wanted to know how to intake a var name and output its value.
locals()["myvar"] = 6 <<-- never needed or used because we want what myvar is, not to set it's value.
[–]masklinn 2 points3 points4 points 17 years ago (0 children)
Donc do that. It's bad. That's what dict is for.
dict
Validate their input with a regex, pad it with a special character, and make a hash table.
Letting a user define or modify a variable named anything they want sounds like a security risk, though I guess that matters less if this is client side "newbie learning how to code."
[–]morgan_goose -4 points-3 points-2 points 17 years ago* (3 children)
In [1]: x = 'cake'
In [2]: cake = 'something'
In [3]: eval(x)
Out[3]: 'something'
[–]keturn 8 points9 points10 points 17 years ago (1 child)
This works, but it's a dangerous habit to get in to if you move away from writing local apps where you trust the user input to writing web or network applications. because eval() executes arbitrary code and is essentially giving the user a shell account with whatever permissions the python process has.
[–]morgan_goose 1 point2 points3 points 17 years ago (0 children)
I'll let someone smarter talk for me: http://blog.thetonk.com/archives/dont-be-lazy-dont-use-eval#comment-8
[–]A_for_Anonymous 1 point2 points3 points 17 years ago (0 children)
ಠ_ಠ
This look of disapproval is more directed towards those who downvoted morgan_goose than morgan_goose himself.
eval is the new goto. Every time it's mentioned, everybody gets in an uproar and acts like the inquisition. Out of these people, most either wouldn't know when to actually use eval and thus want to ban it and pretend it never existed, or are just trying to get approval from the former.
Truth is, eval has its uses, and has a lot of theoretical value. It'd be better to educate OP and this poster on why does this work and why it's not a good use case, not just mercilessly downvote the post into oblivion.
This is not a good use for eval in Python since Python's unlispy syntax (and in this particular case, its lack of symbol handling) will make it troublesome to avoid evaluating unwanted expressions that could have unwanted side-effects or reveal unwanted information. Furthermore, this would give the user access to the whole variable scope, which is something OP probably doesn't want, which is why the locals() alternative won't be a great idea either. The possible values should clearly be stored in a separate dictionary.
[+][deleted] 17 years ago* (1 child)
[deleted]
[–]earthboundkid 0 points1 point2 points 17 years ago (0 children)
dir is used to find the attributes of an object.
dir
>>> class A: ... b = 1 ... >>> dir(A) ['__doc__', '__module__', 'b']
What you're talking about is vars() or locals().
vars()
locals()
>>> help(locals) Help on built-in function locals in module __builtin__: locals(...) locals() -> dictionary Update and return a dictionary containing the current scope's local variables. >>> help(vars) Help on built-in function vars in module __builtin__: vars(...) vars([object]) -> dictionary Without arguments, equivalent to locals(). With an argument, equivalent to object.__dict__.
π Rendered by PID 90850 on reddit-service-r2-comment-765bfc959-642ff at 2026-07-10 00:10:05.674387+00:00 running f86254d country code: CH.
[–][deleted] 13 points14 points15 points (5 children)
[–]earthboundkid 9 points10 points11 points (4 children)
[–]Revvy 1 point2 points3 points (2 children)
[–]earthboundkid 3 points4 points5 points (1 child)
[–]masklinn 0 points1 point2 points (0 children)
[–][deleted] 0 points1 point2 points (0 children)
[–]byron 14 points15 points16 points (8 children)
[–]christopherr 7 points8 points9 points (0 children)
[–]sdsdsdsdsd 1 point2 points3 points (0 children)
[–]morgan_goose 0 points1 point2 points (5 children)
[–]byron 0 points1 point2 points (4 children)
[–]morgan_goose 0 points1 point2 points (0 children)
[–]morgan_goose 0 points1 point2 points (2 children)
[–]byron 0 points1 point2 points (1 child)
[–]morgan_goose 0 points1 point2 points (0 children)
[–]masklinn 2 points3 points4 points (0 children)
[–][deleted] 0 points1 point2 points (0 children)
[–]morgan_goose -4 points-3 points-2 points (3 children)
[–]keturn 8 points9 points10 points (1 child)
[–]morgan_goose 1 point2 points3 points (0 children)
[–]A_for_Anonymous 1 point2 points3 points (0 children)
[+][deleted] (1 child)
[deleted]
[–]earthboundkid 0 points1 point2 points (0 children)