what is the Python equivalent of Ruby's yield?
closures, python, ruby
Solution
Looking more into ruby's yield, it looks like you want something like `contextlib.contextmanager`:
from contextlib import contextmanager
def razz_the_jazz():
print gval
@contextmanager
def quietude(level):
global gval
saved_gval = gval
gval = level
try:
yield
finally:
gval = saved_gval
gval = 1
with quietude(3):
razz_the_jazz()
razz_the_jazz()
This script outputs:
3
1
indicating that our context manager did reset `gval` in the global namespace. Of course, I wouldn't use this context manager since it only works in the global namespace. (It won't work with locals in a function) for example.
This is basically a limitation of how assignment creates a new reference to an object and that you can never mutate an object by assignment to it directly. (The only way to mutate an object is to assign to one of it's attributes or via `__setitem__` (`a[x] = whatever`))
Problem
I'm switching from Ruby to Python for a project. I appreciate the fact that Python has first-class functions and closures, so this question ought to be easy. I just haven't figured out what is idiomatically correct for Python: In Ruby, I could write: ``` def with_quietude(level, &block) begin saved_gval = gval gval = level yield ensure gval = saved_gval end end ``` and call it like this: ``` with_quietude(3) { razz_the_jazz begin_the_beguine } ``` (Note: I'm not asking about Python `try/finally` handling nor about saving and restoring variables -- I just wanted a non-trivial example of wrapping a block inside some other code.) update Or, since some of the answers are getting hung up on the global assignments in the previous example when I'm really asking about closures, what if the call was as follows? (Note that this doesn't change the definition of with_quietude): ``` def frumble(x) with_quietude { razz_the_jazz(x) begin_the_beguine(2 * x) } end ``` How would you implement something similar in Python (and not get laughed at by the Python experts)?