How would you access a local variable defined inside a Python generator from outside the generator?
I have a case where my generator manipulates a local state, and for unittests I want to inspect this state to ensure it contains the correct values.
I can't store the state to an instance variable (e.g. self.state = blah), because I might be creating multiple generators from the same class instance, meaning the generators might overwrite each other's state. I also can't return the state in the yield expression, because the state name may change or vary because individual generator instances.
e.g. I want to do something like this (albeit this code doesn't work)
from random import random
class MyIter(object):
def __iter__(self):
context = {}
for i in xrange(10):
context[random()] = random()
yield i
obj = MyIter()
i1 = iter(obj)
i2 = iter(obj)
while 1:
try:
i1.next()
i2.next()
print i1.context
print i2.context
except StopIteration:
break
Is there anyway to access local variables by inspecting Python's execution stack?
Sorry to answer my own question, but after digging into the generator interface, I found the exact path I need to access the generator's local variables:
from random import random
class MyIter(object):
def __iter__(self):
context = {}
for i in xrange(10):
context[random()] = random()
yield i
obj = MyIter()
i1 = iter(obj)
i2 = iter(obj)
while 1:
try:
i1.next()
i2.next()
print i1.gi_frame.f_locals['context']
print i2.gi_frame.f_locals['context']
except StopIteration:
break
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With