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

Reply via email to