fork download
from contextlib import contextmanager
from inspect import currentframe, getouterframes

@contextmanager
def let(**bindings):
    frame = getouterframes(currentframe(), 2)[-1][0] # 2 because first frame in `contextmanager` is the decorator  
    locals_ = frame.f_locals
    original = {var: locals_.get(var) for var in bindings.keys()}
    locals_.update(bindings)
    yield
    locals_.update(original)

def f():
    x = 1
    with let(x=3):
        print(x)

f()

print(x)
Success #stdin #stdout 0.03s 10244KB
stdin
Standard input is empty
stdout
1
None