Hacker News .hnnew | past | comments | ask | show | jobs | submitlogin

> 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


I 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.


Ha, 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


Cool, I didn't know that could be done. Can it work for global and local variables as well?


You 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.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: