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

Evan Driscoll evaned at gmail.com
Tue Aug 25 15:33:51 EDT 2009


(If you don't want to read the following, note that you can answer my
question by writing a swap function.)

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:

    x = 5
    print x   # prints 5
    with changed_value(x, 10):
        print x  # prints 10
    print x  # prints 5

This is similar to PEP 343's example 5 ("Redirect stdout temporarily";
see http://www.python.org/dev/peps/pep-0343/), except that the
variable that I want to temporarily change isn't hard-coded in the
stdout_redirected function.

What I want to write is something like this:
    @contextmanager
    def changed_value(variable, temp_value):
        old_value = variable
        variable = temp_value
        try:
            yield None
        finally:
            variable = old_value
with maybe a check in 'finally' to make sure that the value hasn't
changed during the execution of the 'with'.

Of course this doesn't work since it only changes the binding of
'variable', not whatever was passed in, and I kind of doubt I can
stick a "&" and "*" in a couple places to make it do what I want. :-)

So my question is: is what I want possible to do in Python? How?

I think it might be possible to rig something up by passing in the
variable that i want to change as a *string* and looking up that
string in a dictionary somewhere, but I think what I need is the locals
() dictionary of the calling function, and I'm not sure how to get
that.

Thanks,
Evan Driscoll



More information about the Python-list mailing list