Context manager to temporarily change the variable of a register [aka write swap(a,b)]

Carl Banks pavlovevidence at gmail.com
Wed Aug 26 11:15:53 EDT 2009


On Aug 25, 1:07 pm, Evan Driscoll <eva... at gmail.com> wrote:
> On Aug 25, 2:33 pm, Evan Driscoll <eva... at 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



More information about the Python-list mailing list