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:47:17 EDT 2009
On Aug 25, 3:25 pm, "Diez B. Roggisch" <de... at nospam.web.de> wrote:
> Modifying locals isn't really allowed - it might stop working with
> certain implementations of python.
>
> And to be honest - I don't really see a use-case for your whole
> approache. Why don't you want to introduce a new name?
Wow, this actually was very helpful, because it forced me to clarify
what I'm doing to myself, and I *am* making it rather too complicated.
The reason that I can't introduce a new name is that I want to call
another function that refers to the old name. (Specifically, I'm using
this in a testing framework, and I want to mock out some things like
file I/O so want to replace 'open' and others temporarily. I don't
really want to make said function take an extra parameter which is
"the open function to use" or something like that.)
But then I don't need to modify locals. In fact, the references that I
want to affect are used in a function that isn't even on the stack
when the "with" statement is entered!
So I only need to modify a global, which is much easier than what I
was mucking about with.
So here is my simplified version that only works for globals:
from contextlib import contextmanager
@contextmanager
def changed_value(var_name, temp_value):
old_value = globals()[var_name]
globals()[var_name] = temp_value
try:
yield None
finally:
globals()[var_name] = old_value
x = 5
print "5:", x
with changed_value("x", 10):
print "10:", x
print "5:", x
y = 7
def test():
print "5:", x
with changed_value("x", 20):
print "20:", x
print "7:", y
print "5:", x
test()
print "5:", x
How does that look?
And thanks for making me think about what I'm doing. :-)
Evan
More information about the Python-list
mailing list