On 30/09/2010 18:07, kj wrote:
This is a recurrent situation: I want to initialize a whole bunch of local variables in a uniform way, but after initialization, I need to do different things with the various variables. What I end up doing is using a dict: d = dict() for v in ('spam', 'ham', 'eggs'): d[v] = init(v) foo(d['spam']) bar(d['ham']) baz(d['eggs']) This is fine, but I'd like to get rid of the tedium of typing all those extra d['...']s. I.e., what I would *like* to do is something closer to this: d = locals() for v in ('spam', 'ham', 'eggs'): d[v] = init(v) foo(spam) bar(ham) baz(eggs) ...but this results in errors like "NameError: global name 'spam' is not defined". But the problem is deeper than the fact that the error above would suggest, because even this fails: spam = ham = eggs = None d = locals() for v in ('spam', 'ham', 'eggs'): d[v] = init(v) foo(spam) # calls foo(None) bar(ham) # calls bar(None) baz(eggs) # calls baz(None) In other words, setting the value of locals()['x'] does not set the value of the local variable x. I also tried a hack using eval: for v in ('spam', 'ham', 'eggs'): eval "%s = init('%s')" % (v, v) but the "=" sign in the eval string resulted in a "SyntaxError: invalid syntax". Is there any way to use a loop to set a whole bunch of local variables (and later refer to these variables by their individual names)?
The handling of local variables in CPython is optimised, so changing locals() won't have any effect, as you discovered. An alternative is to create a namespace in an instance of a class and then add attributes to it: class Namespace(object): pass n = Namespace() for v in ('spam', 'ham', 'eggs'): setattr(n, v, init(v)) foo(n.spam) bar(n.ham) baz(n.eggs) -- http://mail.python.org/mailman/listinfo/python-list