On Jan 22, 8:39 pm, Martin Drautzburg <martin.drautzb...@web.de> wrote:
> Martin Drautzburg wrote: > >> with scope(): > >> # ... > >> # use up, down, left, right here > > >> # up, down, left, right no longer defined after the with block exits. > > Just looked it up again. It's a cool thing. Too bad my locals() hack > would still be required. The result would be less noisy (and actually > really beautiful) than the decorator implementation though. Thanks > again for pointing this out to me. Both in your example and by using a context manager, you can get away with not passing locals() explicitly by introspecting the stack frame. Here's a context manager that does the trick: from __future__ import with_statement from contextlib import contextmanager import sys @contextmanager def enums(*consts): # 2 levels up the stack to bypass the contextmanager frame f_locals = sys._getframe(2).f_locals new_names = set() reset_locals, updated_locals = {}, {} for const in consts: updated_locals[const] = const if const in f_locals: reset_locals[const] = f_locals[const] else: new_names.add(const) f_locals.update(updated_locals) try: yield finally: for name in new_names: del f_locals[name] f_locals.update(reset_locals) if __name__ == '__main__': def move(aDirection): print "moving " + aDirection up = "outerScopeUp" with enums("up", "down", "left", "right"): move(up) move(down) move(left) move(right) print "in the outer scope up is still:", up print "this should fail:" down Of course, as all other attempts to mess with locals() shown in this thread, this only "works" when locals() is globals(). If you try it within a function, it fails: def test(): up = "outerScopeUp" with enums("up", "down", "left", "right"): move(up) move(down) move(left) move(right) print "in the outer scope up is still:", up print "this should fail:" down ## XXX: doesn't work within a function test() So it's utility is pretty limited; a custom DSL is probably better suited to your problem. George -- http://mail.python.org/mailman/listinfo/python-list