Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使生成器/迭代器在耗尽时计算为False?_Python_Iterator_Boolean_Generator - Fatal编程技术网

Python 如何使生成器/迭代器在耗尽时计算为False?

Python 如何使生成器/迭代器在耗尽时计算为False?,python,iterator,boolean,generator,Python,Iterator,Boolean,Generator,Python中的其他空对象的计算结果为False——如何让迭代器/生成器也这样做?默认情况下,Python中的所有对象的计算结果为True。为了支持False求值,对象的类必须具有方法(0->False),或非零方法(False)。注意:Python3.x中的\uuuuu非零==>\uuuuuu bool\uuuu 由于迭代器协议有意保持简单,并且由于有许多类型的迭代器/生成器无法在尝试生成它们之前知道是否有更多的值要生成,True/False计算不是迭代器协议的一部分 如果你真的想要这种行为,

Python中的其他空对象的计算结果为False——如何让迭代器/生成器也这样做?

默认情况下,Python中的所有对象的计算结果为
True
。为了支持
False
求值,对象的类必须具有
方法(
0
->
False
),或
非零方法(
False
)。注意:Python3.x中的
\uuuuu非零
==>
\uuuuuu bool\uuuu

由于迭代器协议有意保持简单,并且由于有许多类型的迭代器/生成器无法在尝试生成它们之前知道是否有更多的值要生成,
True
/
False
计算不是迭代器协议的一部分

如果你真的想要这种行为,你必须自己提供。一种方法是将生成器/迭代器包装在一个提供缺少的功能的类中

请注意,此代码仅在引发
StopIteration
后计算为
False

作为奖励,此代码适用于pythons 2.4+

try:
    next
except NameError:       # doesn't show up until python 2.6
    def next(iter):
        return iter.next()

Empty = object()

class Boolean_Iterator(object):
    """Adds the abilities
    True/False tests:  True means there /may/ be items still remaining to be used
    """
    def __init__(self, iterator):
        self._iter = iter(iterator)
        self._alive = True
    def __iter__(self):
        return self
    def __next__(self):
        try:
            result = next(self._iter)
        except StopIteration:
            self._alive = False
            raise
        return result
    next = __next__                     # python 2.x
    def __bool__(self):
        return self._alive
    __nonzero__ = __bool__              # python 2.x
如果您还需要前瞻(或窥视)行为,则此代码将执行此操作(在引发
StopIteration
之前,其计算结果为
False
):

请记住,当底层迭代器/生成器的计时与其生成的值相关时,peek行为是不合适的


还要记住,第三方代码,可能还有stdlib,可能依赖迭代器/生成器,其计算结果总是
True
。如果希望peek不使用bool,请删除
\uuuu非零\uuuu
\uuuuu bool\uuuu
方法。

Guido不希望生成器和迭代器以这种方式运行

默认情况下,对象为true。只有当它们定义了返回零的_len _uu或返回false的_non zero u(后者在Py3.x中称为_bool u)时,它们才可能为false

您可以将其中一个方法添加到自定义迭代器中,但它与Guido的意图不匹配。他拒绝在已知下一个长度的迭代器中添加_len__。这就是为什么我们得到了长度提示

因此,判断迭代器是否为空的唯一方法是对其调用next()并查看它是否引发StopIteration


在ASPN上,我相信有一些使用这种技术的前瞻包装器的方法。如果提取了一个值,它将保存到下一个()调用中。

一个“空的东西”自动不是迭代器。容器可以是空的,也可以不是空的,您可以在容器上获得迭代器,但是这些迭代器在耗尽时不会出错

迭代器不会出错的一个很好的例子是
sys.stdin
。当
sys.stdin
到达输入端时,将其设为false的问题在于,如果不尝试使用它的输入,就无法真正知道您是否已经到达了这样一个流的末尾。希望迭代器为假的主要原因是“偷看”下一项是否有效;但是对于
sys.stdin
,这显然是不实际的

这是另一个例子

(x for x in xrange(1000) if random.randrange(0, 2))
如果不做大量的工作,就无法知道这个生成器是否会返回更多的数字,实际上,您必须找出下一个值是什么


解决方案是只从迭代器中获取下一个值。如果它是空的,则循环将退出,如果不在循环中,则会出现
StopIteration
异常

我并不是建议所有迭代器/生成器都应该这样做,只是有时候这样做对它们很有用。对于那些时候,我的回答提供了一种实现方法。Guido建议,迭代器/生成器永远不应该以这种方式运行。Python的一个优点是,如果您需要/想要做与“approved”方法不同的事情,它(通常)不会妨碍您。(不要让我开始讲
sum()
ing
str
s!;)这就是所谓的“违背语言的本质”。这意味着您的迭代器在假定
bool(It)
始终为真的代码中不可用。Guido能够生成此类代码的示例,包括他编写的一些代码。(仅仅因为您可以指定False,True=1,0并不意味着您应该;-)确实如此!你能发一个链接到这样的代码吗?我很好奇为什么人们会费心检查总是
True
的东西的真值。空迭代器仍然是迭代器,虽然偷看是主要原因,但不是唯一原因。此外,在布尔测试中使用
StopIteration
也很笨拙;只有容器可以是空的。迭代器是一个“地方”,比如“在开头”,或者“第23行的第5列”。我必须考虑一下。尽管如此,即使按照这些思路,我的代码也可以被认为是
True
如果不是“结束”,那么
False
否则。当您从
sys.stdin
读取时,当按下
ctrl-D
时,迭代器将引发
StopException
好像它是空的,但实际上流不会关闭,它实际上“重新打开”,允许进一步阅读。在所有迭代器类型中都没有一致的空概念。唯一一致可用的功能是
next()
,它可能会引发
StopIteration
,也可能不会。你说的“StopException”——你是说
StopIteration
?一旦提出了
StopIteration
,就应该在进一步的
next()
调用或迭代器有趣的问答中继续提出它,可以利用
inspect.getgeneratorstate()
来实现这一点吗?
(x for x in xrange(1000) if random.randrange(0, 2))