首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何防止评估短路?

如何防止评估短路?
EN

Stack Overflow用户
提问于 2012-09-05 20:29:45
回答 2查看 6.8K关注 0票数 26

这是我在Django项目中遇到的一个问题。这是关于表单验证的。

在Django中,当您有一个提交的表单时,您可以在相应的表单对象上调用is_valid()来触发验证并返回一个布尔值。因此,通常在视图函数中有类似这样的代码:

代码语言:javascript
复制
if form.is_valid():
    # code to save the form data

is_valid()不仅会验证表单数据,还会将错误消息添加到表单对象中,然后显示给用户。

在一个页面上,我同时使用两个表单,并且仅当两个表单都包含有效数据时才保存数据。这意味着在执行保存数据的代码之前,我必须在这两个表单上调用is_valid()。最明显的方式是:

代码语言:javascript
复制
if form1.is_valid() and form2.is_valid():
    # ...

不会工作,因为逻辑运算符的短路计算。如果form1无效,则不会对form2求值,并且其错误消息将丢失。

这只是一个例子。据我所知,在其他语言(即Smalltalk)中,没有比and/or更贪婪的选择。我可以想象这个问题会在不同的环境下发生(不仅仅是在Python中)。我能想到的解决方案都很笨拙(嵌套的if,将返回值赋给局部变量并在if语句中使用它们)。我想知道解决这类问题的方法。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-09-05 20:32:46

不如这样吧:

代码语言:javascript
复制
if all([form1.is_valid(), form2.is_valid()]):
   ...

在一般情况下,可以使用列表理解,以便预先计算结果(与此上下文中通常使用的生成器表达式相反)。例如:

代码语言:javascript
复制
if all([ form.is_valid() for form in (form1,form2) ])  

这也将很好地扩展到任意数量的条件...唯一的问题是,它们都需要通过"and“连接,而不是if foo and bar or baz: ...

(对于非短路or,可以使用any而不是all)。

票数 38
EN

Stack Overflow用户

发布于 2019-12-20 02:30:32

您可以使用Infix operators (ActiveState Python配方)来定义您自己的布尔运算符:

代码语言:javascript
复制
aand = Infix(lambda x,y: bool(x) and bool(y))
1 |aand| 2  # Will return `True` instead of `1`
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12281469

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档