Does this work for user defined classes (objects) as well?
Yes, and by the same mechanism and for the same reason.
I’ve never thought that leaking this type of implementation detail into the return value (and return type!) was a nice solution. I like the double closure better, and one can shorten it a bit with a lambda.
For those who prefer a functional style, functools.partial can also solve this problem.
(I use Python, and I like a lot of things about Python, but I don’t like its scoping rules at all, nor do I like the way that Python’s closures work. I would use a double lambda.)
Another way to use function arguments to fix it is to put another level of function in:
def loop():
for number in range(10):
def make_closure(n):
def closure():
return n
return closure
yield make_closure(number)
[1] side note, closures in python are always late-binding, which is what causes the behavior in OP