我怎样才能用尽时,发电机/迭代器评估为假? [英] How can I get generators/iterators to evaluate as False when exhausted?

查看:105
本文介绍了我怎样才能用尽时,发电机/迭代器评估为假?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Python中的其他空对象评估为假 - 我怎样才能得到迭代器/发电机也这样做。

Other empty objects in Python evaluate as False -- how can I get iterators/generators to do so as well?

推荐答案

默认情况下所有的Python对象评估为。为了支持评估对象的类必须有一个 __ LEN __ 办法( 0 - > )或 __非零__ 办法( - > )。注: __ __非零 ==> __ __ BOOL 在Python 3.X

By default all objects in Python evaluate as True. In order to support False evaluations the object's class must have either a __len__ method (0 -> False), or a __nonzero__ method (False -> False). Note: __nonzero__ ==> __bool__ in Python 3.x.

由于迭代器协议是故意保持简单,因为有很多类型的迭代器/发电机是不能够知道是否还有更多的值试图生产它们,真之前产生 / 评价不迭代器协议的一部分。

Because the iterator protocol is intentionally kept simple, and because there are many types of iterators/generators that aren't able to know if there are more values to produce before attempting to produce them, True/False evaluation is not part of the iterator protocol.

如果你真的想这样的行为,你必须自己提供。一种方法是包住发生器/迭代中,提供了缺少的功能的类。

If you really want this behavior, you have to provide it yourself. One way is to wrap the generator/iterator in a class that provides the missing functionality.

请注意,这code只计算结果为 的StopIteration 有后被提出。

Note that this code only evaluates to False after StopIteration has been raised.

作为奖励,这code适用于蟒蛇2.4 +

As a bonus, this code works for 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

如果你也想先行(或PEEK)的行为,这code会做的伎俩(计算结果为 的StopIteration 升至):

If you also want look-ahead (or peek) behavior, this code will do the trick (it evaluates to False before StopIteration is raised):

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

Empty = object()

class Iterator(object):
    """Adds the abilities
    True/False tests:  True means there are items still remaining to be used
    peek(): get the next item without removing it from the sequence
    """
    def __init__(self, iterator):
        self._iter = iter(iterator)
        self._peek = Empty
        self.peek()
    def __next__(self):
        peek, self._peek = self._peek, Empty
        self.peek()
        if peek is not Empty:
            return peek
        raise StopIteration
    next = __next__                     # python 2.x
    def __bool__(self):
        return self._peek is not Empty
    __nonzero__ = __bool__              # python 2.x
    def peek(self):
        if self._peek is not Empty:
            return self._peek
        self._peek = next(self._iter, Empty)
        return self._peek

请注意,偷看当底层迭代/发电机的定时是相关的其产生的值的行为是不恰当的。

Keep in mind that peek behaviour is not appropriate when the timing of the underlying iterator/generator is relevant to its produced values.

也请记住第三方code,以及可能的STDLIB,可以依靠迭代器/发电机总为。如果你想偷看没有布尔,删除 __ __非零 __ __ BOOL 方法。

Also keep in mind that third-party code, and possibly the stdlib, may rely on iterators/generators always evaluating to True. If you want peek without bool, remove the __nonzero__ and __bool__ methods.

这篇关于我怎样才能用尽时,发电机/迭代器评估为假?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆