布尔';和'';或';用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