布尔';和'';或';用Python?

布尔';和'';或';用Python?,python,parsing,operator-keyword,Python,Parsing,Operator Keyword,例如,这些在中定义,可以这样使用: import operator print operator.__add__ # alias add -> + print operator.__sub__ # alias sub -> - print operator.__and__ # alias and_ -> & print operator.__or__ # alias or_ -> | 那么和和或的等价物是什么 print operator."a

例如,这些在中定义,可以这样使用:

import operator
print operator.__add__   # alias add -> +
print operator.__sub__   # alias sub -> -
print operator.__and__   # alias and_ -> &
print operator.__or__    # alias or_ -> |
那么
的等价物是什么

print operator."and ?????"  # should be boolean-and
print operator."or ????"    # should be boolean-or

运算符在运算符模块中没有等效项,因为它们不能作为函数实现。这是因为它们是短路的:它们可能不会根据第一个操作数的结果计算第二个操作数。

这些操作数不存在。您最好将其替换为lambda:

band = (lambda x,y: x and y)
bor = (lambda x,y: x or y)
原因是您无法实现
的完整行为,因为它们会短路

例如:

如果
变量
,则永远不会调用要执行的
长操作
,因为Python知道
无论如何都必须返回
。这是一个优化。大多数情况下,这是一个非常理想的特性,因为它可以节省大量无用的处理

但这意味着你不能让它成为一个函数:

例如:

在这种情况下,甚至在计算之前就调用了执行的
long\u fonction\u


幸运的是,考虑到您使用生成器和列表理解,您很少需要这样的东西。

e-satis答案的扩展:

lazyand = (lambda x,y: x() and y())
lazyor = (lambda x,y: x() or y())
这里的区别在于传入的条件本身就是thunk(形式为“()->value”的函数),它们只在需要时进行计算。(可以说,只有
y
需要惰性地进行评估,但我这样写是为了保持一致性)

也就是说,这保留了
(和
)的“惰性”方面,但代价是更详细的代码和更多的对象/方法调用

andexpr = lazyand(lambda: false, lambda: never_executed())
andexpr() # false
不过,我很难真正推荐使用这种方法——需要注意的是,这些thunk必须是明确的,如上所示。这可能是未包含在
操作员
模块中的原因之一。其他一些语言允许按名称传递或隐式“提升”


快乐编码。

问题是什么
必须是特殊的,因为它们短路。如果您不希望函数等效(即短路),只需使用lambda即可。这是一个真正的问题,即使没有写清楚。我投票赞成重新打开,因为它已被重写,而且问题本身很有趣。+1表示重新打开;这个问题是绝对相关的。他们缺席的理由很好,当然不会短路。很好,+1。但当然,这意味着参数是可调用的,因此这不适用于属性、惰性gettext转换字符串或ORM queryset。无论如何,在一些非常特殊的情况下,它可以作为band和bor的一个很好的替代品
lazyand = (lambda x,y: x() and y())
lazyor = (lambda x,y: x() or y())
andexpr = lazyand(lambda: false, lambda: never_executed())
andexpr() # false