【问题标题】:Nested iterator accessing variable from the method it's nested in嵌套迭代器从它嵌套的方法访问变量
【发布时间】:2014-07-31 13:39:40
【问题描述】:

我想创建一个迭代器,在使用它时计算另一个迭代器的长度。 这是我想要实现的工作示例:

from random import random

def randleniter(p):
    while random() < p:
        yield 7

count = 0

def do():
    def countiter(piter):
        global count
        for i in piter:
            count += 1
            yield i
    list(countiter(randiter(0.99))) #simulator for a different method consuming the iterator
    return count

>>> do()
81

但是,如果我打算使用全局变量,我永远不会这样构建它。我想,因为我可以用嵌套方法做到这一点:

def make_adder(x):
    def add(y):
        return x + y
    return add

我可以这样做:

def do():
    count = 0
    def countiter(piter):
        for i in piter:
            count += 1
            yield i
    list(countiter(randiter(0.99)))
    return count

但这会导致UnboundLocalError: local variable 'count' referenced before assignment。当我从countiter 内部print locals() - 它不包括count。 我可以让countiter 以某种方式访问​​count 吗?

【问题讨论】:

  • 为什么不做一个简单的类
  • @PadraicCunningham 当然,创建一个简单的类可以解决它。这就是为什么我的问题不是“如何使这项工作”——我想在这个过程中学习:)
  • 显然,生成器不能用于“闭包时尚”。
  • @Jan-PhilipGehrcke 我认为这是重复的,不相关。我刚刚确切地了解了闭包是什么,所以我不知道要搜索那个关键字。 (根据我发现的定义,这甚至不是真正的闭包,因为封闭范围没有完成它的执行)

标签: python python-2.7 iterator


【解决方案1】:

您所描述的内容被称为closure,这是一个完全独立于迭代器和生成器的主题。 Python3.x 有nonlocal 关键字(只需在计数器中声明nonlocal count 以匹配您所需的行为,在python 2.7 中,您必须通过可变对象模拟它(因为内部函数可以readmutate 外部函数变量,而不是assign 给他们)。

所以你实际上可以这样做:

def do():
    count = [0,]
    def countiter(iter):
        for i in iter:
            count[0] += 1
            yield i
    list(countiter(randiter(0.99)))
    return count[0]

【讨论】:

  • 您在编辑中建议的代码正是我在接受答案之前运行的代码。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-24
  • 1970-01-01
相关资源
最近更新 更多