访问Python生成器中的局部变量

Cer*_*rin 6 python scripting iterator generator

您如何从生成器外部访问Python生成器中定义的局部变量?

我有一个案例,我的生成器操纵一个本地状态,对于单元测试我想检查这个状态,以确保它包含正确的值.

我无法将状态存储到实例变量(例如self.state = blah),因为我可能正在从同一个类实例创建多个生成器,这意味着生成器可能会覆盖彼此的状态.我也无法在yield表达式中返回状态,因为状态名称可能因个别生成器实例而改变或变化.

例如,我想做这样的事情(虽然这段代码不起作用)

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
Run Code Online (Sandbox Code Playgroud)

无论如何通过检查Python的执行堆栈来访问局部变量?

Cer*_*rin 4

很抱歉回答我自己的问题,但是在深入研究生成器接口后,我找到了访问生成器局部变量所需的确切路径:

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
Run Code Online (Sandbox Code Playgroud)

  • 哎哟! 不要这样做,这是 CPython 的实现细节。它可能会随着新版本的变化而变化,并且对于不同的 Python 实现(例如 Jython 或 IronPython)会有所不同。而且它的可读性也不是很好...... (3认同)