讨论here
提示 的行为建议了一些等效代码等效代码的行为是否应被视为定义的一部分,或者实现是否可以以非短路方式实现它们?
以下是cpython / Lib / test / test_builtin.py的相关摘录
def test_all(self):
self.assertEqual(all([2, 4, 6]), True)
self.assertEqual(all([2, None, 6]), False)
self.assertRaises(RuntimeError, all, [2, TestFailingBool(), 6])
self.assertRaises(RuntimeError, all, TestFailingIter())
self.assertRaises(TypeError, all, 10) # Non-iterable
self.assertRaises(TypeError, all) # No args
self.assertRaises(TypeError, all, [2, 4, 6], []) # Too many args
self.assertEqual(all([]), True) # Empty iterator
S = [50, 60]
self.assertEqual(all(x > 42 for x in S), True)
S = [50, 40, 60]
self.assertEqual(all(x > 42 for x in S), False)
def test_any(self):
self.assertEqual(any([None, None, None]), False)
self.assertEqual(any([None, 4, None]), True)
self.assertRaises(RuntimeError, any, [None, TestFailingBool(), 6])
self.assertRaises(RuntimeError, all, TestFailingIter())
self.assertRaises(TypeError, any, 10) # Non-iterable
self.assertRaises(TypeError, any) # No args
self.assertRaises(TypeError, any, [2, 4, 6], []) # Too many args
self.assertEqual(any([]), False) # Empty iterator
S = [40, 60, 30]
self.assertEqual(any(x > 42 for x in S), True)
S = [10, 20, 30]
self.assertEqual(any(x > 42 for x in S), False)
它没有采取任何措施来强制执行短路行为
答案 0 :(得分:39)
保证行为。我贡献了一个patch,最近被接受并且merged,所以如果您获取最新的来源,您会看到现在明确强制执行了短路行为。
git clone https://github.com/python/cpython.git
grep Short-circuit cpython/Lib/test/test_builtin.py
答案 1 :(得分:12)
文档说
“如果iterable的任何元素为true,则返回True。如果iterable为空,则返回False。 EQUIVALENT TO:”(强调我的)...
def any(iterable):
for element in iterable:
if element:
return True
return False
如果any
未发生短路,则对发布的代码不会 EQUIVALENT ,因为发布的代码明显短路。例如,您可以消耗比您想要的更多的生成器。鉴于此,我说保证短路行为。
all
可以使用完全相同的参数。
答案 2 :(得分:1)
它可以短路,因为它可以被赋予非绑定的可迭代性。如果它没有短路,那么这将永远不会终止:
any(x == 10 for x in itertools.count())
答案 3 :(得分:0)
这是我搜索“所有短路python”时出现的唯一堆栈溢出页面
因此:如果您着陆在这里寻找简单的“是否/总是总是短路?”
他们做到了,但是有一个陷阱:使用列表理解可以使其似乎,就像您要覆盖短路行为一样:
def hi_test():
print('hi')
return True
>>> any(hi_test() for num in [1, 2, 3, 4])
hi
>>> any([hi_test() for num in [1, 2, 3, 4]])
hi
hi
hi
hi
列表推导要在any()之前执行。