11 ms·
> There's no way to abstract out that pattern in Python. I'm sure there are macros that can't be abstracted out in Python but this isn't one of them: from
by reinhardt 14y ago
> There's no way to abstract out that pattern in Python.
I'm sure there are macros that can't be abstracted out in Python but this isn't one of them:
from contextlib import contextmanager
@contextmanager
def temp_assign(obj, attr, val):
old_val = getattr(obj, attr)
setattr(obj, attr, val)
yield
setattr(obj, attr, old_val)
class X:
pass
x = X()
x.a = 1
with temp_assign(x, "a", 2):
print x.a # prints 2
print x.a # prints 1
- hythloday 14y agoI think it's an extraordinary strength of Python that I hadn't seen your code when writing mine but that other than two variable names they're identical. Leaving my comment up for demonstration of this.
- reinhardt 14y agoHa, awesome! I went for an exact transliteration although if I were to use this idea for real I would probably do the assignment explicitly in the body. I think this looks a bit more pythonic: @contextmanager def restoring(obj, attr): old_val = getattr(obj, attr) yield setattr(obj, attr, old_val) x.a = 1 with restoring(x, "a"): print x.a x.a = 2 print x.a print x.a
- ced 14y agoCool, I didn't know that could be done. Can it work for global and local variables as well?
- timClicks 14y agoYou can do anything you want with a context manager, it's just Python. IIRC, they were first added to the language to get rid of boilerplate while acquiring/releasing locks to make multi-threading easier.