I'm trying to learn more about generator functions in Python. To my knowledge, generator functions don't fully return until there are no more yield calls, so a stack frame exists in the generator returned by the function.
Stack frames should have references to a callable function, so my question is: how can I get that callable function from the generator?
When running the code below, I have a generator function, test().
def test():
for i in range(10):
yield i
generator = test()
In this example, is there any way to get the callable function test() from generator?
After looking at this answer, it seems like CPython keeps track of some of these like generator.frame and generator.code, however, I can't seem to convert those objects into functions.
I need the callable function. Something like this:
func = generator.something_special
new_generator = func()
1 Answer 1
You can use the __name__ attribute to get the name of the original function then access it inside locals provided it's still in scope.
def test():
for i in range(10):
yield i
generator = test()
print(list(generator))
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
func_name = generator.__name__
new_generator = locals()[func_name]()
print(func_name, list(new_generator))
# test [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
2 Comments
globals() instead of locals(). However, using globals() will make it always work regardless of scope.locals() won't pick it up but globals() usually will. Heads up btw using globals and locals gets risky fast. I recommend doing some googling on some of the pitfalls of using them.Explore related questions
See similar questions with these tags.
test()function so it's never going to be in the current stack - it literallyyielded the execution back to its caller (i.e.main()). If you want a bit more detail this thread dives into how generators work.