Thanks Steven.
On Nov 4, 2011, at 6:45 PM, Steven D'Aprano wrote:
> Max S. wrote:
>> Is it possible to create a variable with a string held by another variable
>> in Python? For example,
>
> Yes, but you shouldn't do it. Seriously. Don't do this, you will regret it.
>
> var_name = input("Variable name? ") # use raw_input in Python 2
> exec("%s = 4" % var_name)
>
>
> Instead, you should use a dictionary, like this:
>
> var_name = input("Variable name? ")
> table = {var_name: 4}
>
> and then later when you need to retrieve the value:
>
> print(table[var_name])
>
>
>
> Why shouldn't you use exec?
>
> Three main reasons:
>
> (1) This code contains a MAJOR vulnerability to a code injection attack.
> There are enough code injection vulnerabilities in the world without you
> adding to it, please don't add another.
>
> (2) It makes for hard to read, difficult to follow code.
>
> (3) It's slow.
>
>
> If you don't know what code injection attacks means, consider this simple
> example where I create a variable spam=4 while executing any code I like:
>
> >>> var_name = input('Enter the variable name: ')
> Enter the variable name: print(123*456); spam
> >>> exec("%s = 4" % var_name)
> 56088
> >>> spam
> 4
>
>
> In this case, executing "print(123*456)" is harmless, but annoying, but it
> could do *anything* that Python can do (which is pretty much *anything at
> all*: delete files, send email, take over your computer, anything). Code
> injection attacks are among the two or three most common methods that viruses
> and malware operate.
>
> Sanitising user input so it is safe to pass to exec is a hard job. But
> suppose you do it (somehow!):
>
> var_name = sanitise(input('Enter the variable name: '))
> exec("%s = 4" % var_name)
> # ...
> # ... later on
> # ...
> print(spam+1) # do something useful with the new variable
>
> But wait, that can't work! How do you know that the variable is called
> "spam"? You don't. It could be called anything. So now you have to do this:
>
> exec("print(%s+1)" % var_name)
>
> which is a nuisance, it is harder to read and harder to follow, and defeats
> any of the useful features in your editor or IDE. It gets worse if you need
> to use this var_name repeatedly:
>
> exec("print(%s+1)" % var_name)
> exec("my_list = [1, 2, 3, %s, 5]" % var_name)
> print(my_list)
> exec("y = func(23, %s, 42) + %s" % (var_name, var_name))
> print(y)
>
> How tedious and painful and hard to follow. And it is potentially buggy: what
> if the user typed "func" as the variable name, by accident? Or over-wrote one
> of your other variables?
>
> And it's slow. Every time you call exec(), Python has to run a
> mini-interpreter over the string, analyzing it, splitting it into tokens,
> compiling it into code that can be executed, and then finally execute it. In
> general, this is slow: in my experience, running exec("command") is about 10
> times slower than just running command directly.
>
> So just avoid using exec. Anytime you think you need exec, you almost
> certainly do not. And you definitely don't need it for indirect variables!
> Just use a dictionary instead:
>
> var_name = input("Variable name? ")
> table = {var_name: 4}
> # ...
> # ... later on
> # ...
> print(table[var_name]+1)
> my_list = [1, 2, 3, table[var_name], 5]
> print(my_list)
> y = func(23, table[var_name], 42) + table[var_name]
> print(y)
>
>
>
>
> --
> Steven
>
> _______________________________________________
> Tutor maillist - [email protected]
> To unsubscribe or change subscription options:
> http://mail.python.org/mailman/listinfo/tutor
_______________________________________________
Tutor maillist - [email protected]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor