Old Python 2 exec will change the bytecode to search for both local and global namespaces.
As you define a = 2 globally, this is the one that is discovered when commenting on a = 1 . When you uncomment a = 3 , it is a "found", but not yet defined.
If you read how character tables are handled in this great article by Eli Bendersky , you can better understand how local variables are handled.
You should not use exec for this type of code (I hope this is not production code), and it will break anyway when porting your code to Py3k:
The Python 3 exec function is no longer an operator and therefore cannot change the environment in which it resides.
Perhaps I should go directly to the point:
If you do all this dynamic naming, you should use a dictionary:
def f(): data = {'a': 1} data['a'] = 2 if ...: data['a'] = 3
Jbernardo
source share