Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
# Closures + Generators: Check yourself before you wreck yourself
def outer():
for x in range(10):
a = x
def inner():
print(a)
yield inner
# Sequential call, can't tell anything is wrong
for inner in outer():
inner()
# Non-Sequential call, oh snap. What I would want is when you create the
# inner function, it creates a closure that is not affected by rebinding
# by the outer function after it is created (essentially just copy the
# scope dict)
for inner in list(outer()):
inner()
# Here is _A_ way to fix this, please fork and show me something slicker
def outer_sticky_scope():
for x in range(10):
a = x
def inner0(scope):
def inner1():
print(scope['a'])
return inner1
yield inner0(dict(locals()))
for inner in outer_sticky_scope():
inner()
for inner in list(outer_sticky_scope()):
inner()
# Here's something a bit nastier, but you don't have to change your inner function
# this works because you can create a new scope for a code object using eval
def outer_sticky_scope2():
for x in range(10):
a = x
def inner0(scope):
def inner1():
print(a)
return lambda : eval(inner1.__code__, globals(), scope)
yield inner0(dict(locals()))
for inner in outer_sticky_scope2():
inner()
for inner in list(outer_sticky_scope2()):
inner()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment