Python3.8 `all()` 没有短路
Python3.8 `all()` not short circuiting
好吧,我可能只是今天工作不顺利,但据我所知 all()
应该短路 according to the docs。
all()
应该等同于:
def all(iterable):
for element in iterable:
if not element:
return False
return True
这也相当于菊花链 and
。
所以下面应该做同样的事情:
all((True, print('This should print and stop'), print("this shouldn't print")))
True and print('This should print and stop') and print("this shouldn't print")
但最上面的两个打印件都打印了(即对每个部分进行了全面评估)
但是底部正确短路了。
这是 Python (3.8.2) 的错误还是我突然没弄对?
all
内部的迭代短路,但每次调用 print
都必须进行评估,以创建您在 all
之前作为参数传递的 tuple
曾经被称为。
没有 def
语句就没有在 Python 中创建任意惰性序列的简单方法。你可以写
def foo():
yield True
yield print("This should print and stop")
yield print("this shouldn't print")
all(foo())
但是没有等价的纯表达式。您需要迭代 something 才能使用生成器表达式,例如
(x(y) for x, y in zip([id, print, print],
[True,
"This should print and stop",
"this shouldn't print"]))
会如您所愿地工作。
>>> all(x(y) for x, y in zip([id, print, print], [True, "This should print and stop", "this shouldn't print"]))
This should print and stop
False
现在,print
在 all
内部被调用,而不是作为评估传递给 all
的参数的一部分。
Python的all
拿一个iterable as an argument
在构建您问题中的示例(在本例中为元组)期间,调用元组文字中的函数,并将 return 值插入到元组文字中;无异于:
>>> tup=(True, print('this'), False, print('not this'))
this
not this
如果你想要assemble的形式你可以这样做:
def example_func(*args):
return args
g2all=(True, (print, 'this', 'and this'), False, (print, 'not this'), (example_func,1,2,3,4))
这是因为您可以通过名称引用函数,并且在没有 ()
调用运算符的情况下,函数尚未被调用:
>>> g2all
(True, (<built-in function print>, 'this', 'and this'), False, (<built-in function print>, 'not this'), (<function example_func at 0x10d0a9430>, 1, 2, 3, 4))
然后您可以在带有生成器的 all
中使用它:
>>> all(f[0](*tuple(f[1:])) if isinstance(f, tuple) and callable(f[0]) else f for f in g2all)
this and this
False
并且当 all
找到 Falsie 值时函数调用停止。
好吧,我可能只是今天工作不顺利,但据我所知 all()
应该短路 according to the docs。
all()
应该等同于:
def all(iterable):
for element in iterable:
if not element:
return False
return True
这也相当于菊花链 and
。
所以下面应该做同样的事情:
all((True, print('This should print and stop'), print("this shouldn't print")))
True and print('This should print and stop') and print("this shouldn't print")
但最上面的两个打印件都打印了(即对每个部分进行了全面评估) 但是底部正确短路了。
这是 Python (3.8.2) 的错误还是我突然没弄对?
all
内部的迭代短路,但每次调用 print
都必须进行评估,以创建您在 all
之前作为参数传递的 tuple
曾经被称为。
没有 def
语句就没有在 Python 中创建任意惰性序列的简单方法。你可以写
def foo():
yield True
yield print("This should print and stop")
yield print("this shouldn't print")
all(foo())
但是没有等价的纯表达式。您需要迭代 something 才能使用生成器表达式,例如
(x(y) for x, y in zip([id, print, print],
[True,
"This should print and stop",
"this shouldn't print"]))
会如您所愿地工作。
>>> all(x(y) for x, y in zip([id, print, print], [True, "This should print and stop", "this shouldn't print"]))
This should print and stop
False
现在,print
在 all
内部被调用,而不是作为评估传递给 all
的参数的一部分。
Python的all
拿一个iterable as an argument
在构建您问题中的示例(在本例中为元组)期间,调用元组文字中的函数,并将 return 值插入到元组文字中;无异于:
>>> tup=(True, print('this'), False, print('not this'))
this
not this
如果你想要assemble的形式你可以这样做:
def example_func(*args):
return args
g2all=(True, (print, 'this', 'and this'), False, (print, 'not this'), (example_func,1,2,3,4))
这是因为您可以通过名称引用函数,并且在没有 ()
调用运算符的情况下,函数尚未被调用:
>>> g2all
(True, (<built-in function print>, 'this', 'and this'), False, (<built-in function print>, 'not this'), (<function example_func at 0x10d0a9430>, 1, 2, 3, 4))
然后您可以在带有生成器的 all
中使用它:
>>> all(f[0](*tuple(f[1:])) if isinstance(f, tuple) and callable(f[0]) else f for f in g2all)
this and this
False
并且当 all
找到 Falsie 值时函数调用停止。