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

Evan Driscoll evaned at gmail.com
Tue Aug 25 16:07:13 EDT 2009


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



More information about the Python-list mailing list