On Aug 25, 1:07 pm, Evan Driscoll <eva...@gmail.com> wrote: > On Aug 25, 2:33 pm, Evan Driscoll <eva...@gmail.com> wrote: > > > I want to make a context manager that will temporarily change the > > value of a variable within the scope of a 'with' that uses it. This is > > inspired by a C++ RAII object I've used in a few projects. Ideally, > > what I want is something like the following: > > Okay, so I think I actually got this with some consultation with a > friend. Critiques? > > from contextlib import contextmanager > import inspect > > def get_parents_var(offset, var): > f = inspect.stack()[offset][0] > if var in f.f_locals: > return f.f_locals[var] > else: > return f.f_globals[var] > > def set_parents_var(offset, var, val): > f = inspect.stack()[offset][0] > if var in f.f_locals: > f.f_locals[var] = val > elif var in f_globals: > f.f_globals[var] = val > else: > assert False > > @contextmanager > def changed_value_tb(var_name, temp_value): > # 1 is here, 2 will be the implicit next() function, 3 is the > real caller > offset = 3 > old_value = get_parents_var(offset, var_name) > set_parents_var(offset, var_name, temp_value) > try: > yield None > finally: > set_parents_var(offset, var_name, old_value) > > x = 5 > print x # prints 5 > with changed_value_tb("x", 10): > print x # prints 10 > print x # prints 5
Well, it wouldn't be a "can I rebind a variable using a with- statement" thread if someone didn't post a solution that they thought worked, but didn't test it on local variables. Carl Banks -- http://mail.python.org/mailman/listinfo/python-list