0

使用内置assert语句,是否有一种很好的 Pythonic 方法来检查迭代中的空虚?我见过:

但我正在寻找使用断言的解决方案。以下看起来可行,但我不确定我是否遗漏了一些重要的可能异常:

a = [1, 2, 3]
b = []

assert a, 'a is empty'
assert b, 'b is empty'

这引发了这一点AssertionError

Traceback (most recent call last):
  File "<ipython-input-9-185714f6eb3c>", line 5, in <module>
    assert b, 'b is empty'
AssertionError: b is empty
4

2 回答 2

4

记住不要混淆 a container(想想列表、集合、元组、字典等)和 an iterable(任何可以产生新状态的东西)。检查 an 是否为“空”的唯一方法iterable是尝试迭代它并确定它是否不会产生至少一个新状态。您可以自由地将其解释为iterable“空”。

像这样的东西

def test_thing_is_empty(self):  # We are in a unittest.Testcase
    foo = iter([])  # Or any other iterable thing
    try:
        item = next(foo)
    except StopIteration:
        pass  # This is what should happen
    else:
        self.fail("Expected foo to be empty, got %s" % (item, ))

还要记住,从iterable技术上讲,an 永远不会真正“空”。尽管不鼓励,但允许有时iterable抛出 a StopIteration,如果再次尝试,突然开始产生新元素。

因此没有办法做到assert这一点。你必须尝试看看你是否失败。如果你确实失败了,唯一真正的知识是现在iterable没有产生新的状态(无论出于何种原因)。如果你拿回了一个项目,那么iterable刚刚产生了一个独特的、珍贵的雪花,它可能永远无法再重现(想想从堆栈中某处的网络套接字读取)。

于 2016-12-22T17:01:23.043 回答
-2

怎么样:

assert len(a), "a is empty"

assert a, ...它与for和objects具有相同的效果list,但您可能会发现它看起来更清晰/更易于维护。dictset

也不保证对任意可迭代对象起作用,尽管您可能会发现后者更可取,因为它会为没有的可迭代对象抛出异常assert a, ...,而不是可能让断言以误报通过。看起来没有完全通用的解决方案(即,您无法构造一个可以击败它的可迭代的解决方案)。assert len(a), ...__len__

于 2016-12-22T16:59:47.253 回答