这个“and”语句实际上在返回中做了啥?
Posted
技术标签:
【中文标题】这个“and”语句实际上在返回中做了啥?【英文标题】:What is this "and" statement actually doing in the return?这个“and”语句实际上在返回中做了什么? 【发布时间】:2013-06-21 17:23:31 【问题描述】:我试图更好地理解下面的python代码以及作者为什么在return中使用“AND”语句。
def valid_password(self, password):
PASS_RE = re.compile(r'^.6,128$')
return password and PASS_RE.match(password)
进一步的代码...
if not self.valid_password(self.password):
params['error_password'] = "Please enter a valid password."
我尝试检查返回给调用者的结果对象,但我仍然不完全理解它是如何工作的。
似乎这会将密码返回给调用者以及密码是否有效的布尔值,但是我不明白调用函数如何检查对象的布尔值?这是我错过的关于 Python 的基本知识吗?
在这个例子旁边还有另一个类似用法的例子,但是它使用了“或”语句,这对我来说更令人困惑:
def valid_email(self, email):
EMAIL_RE = re.compile(r'^[\S]+@[\S]+\.[\S]+$')
return not email or EMAIL_RE.match(email)
任何关于这里到底发生了什么的建议将不胜感激。该代码可以正常工作并执行您期望它执行的操作,根据正则表达式验证输入并返回 True 或 False,但是我真的很想了解它是这样写的,而不是简单地返回 bool。
【问题讨论】:
嘿,伙计,我试图在我的回答中解释用于这些表达式的构建块,基本上是短路评估和 python 真值——它们是任何语言的重要概念。如果您需要更多说明,请告诉我。 【参考方案1】:在 Python 中,and
和 or
都将返回它们的操作数之一。使用or
,Python 检查第一个操作数,如果它是“真实”值(稍后将详细介绍真实性),它会返回第一个值而不检查第二个值(这称为布尔快捷评估,它可能很重要) .如果第一个是“falsey”,那么 Python 返回第二个操作数,不管它是什么:
Python 2.7.3 (default, Jan 2 2013, 13:56:14)
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 2 or 3
2
>>> 0 or 3
3
使用“and”,会发生很多相同的事情:首先检查第一个操作数,如果它是“假”,那么 Python 永远不会检查第二个操作数。如果第一个操作数是“真”,那么 Python 返回第二个操作数,不管它是什么:
>>> 2 and 3
3
>>> 0 and 3
0
>>> 3 and 0
0
>>> 3 and []
[]
>>> 0 and []
0
现在我们来谈谈“真”和“假”。 Python 使用以下规则在布尔上下文中评估事物:
以下值为“falsey”:False、None、0(零)、[](空列表)、()(空元组)、(空字典)、空集、“” (空字符串) 其他一切都是“真实的”所以像 password and PASS_RE.match(password)
这样的东西正在利用 Python 的短路评估。如果password
是None,那么and
运算符将只返回None,并且永远不会评估后半部分。这很好,因为PASS_RE.match(None)
会抛出异常。观看:
>>> 3 or []
3
>>> [] or 3
3
>>> 0 or []
[]
>>> [] or 0
0
>>> 0 and []
0
>>> [] and 0
[]
看看短路是如何工作的?现在看这个:
>>> value = "hello"
>>> print (value.upper())
HELLO
>>> print (value and value.upper())
HELLO
>>> value = None
>>> print (value.upper())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'upper'
>>> print (value and value.upper())
None
了解and
的短路功能如何帮助我们避免回溯?这就是这个函数中发生的事情。
【讨论】:
事实上,其他答案恰好有一半是正确的。所以这个答案是不正确,因为它声称大多数其他答案都是不正确的。而且我还是不喜欢“真”和“假”,因为这暗示着它们“有点真”或“有点假”。 当我开始写这篇文章时,它肯定是“最”的。 :-) 我认为当时有三个答案,只有一个没有说“这会返回一个布尔值”。 显示在可以编辑答案时编写此类内容的危险。 :-) 我想我会编辑我的说“几个”其他答案不正确。 :-) @LennartRegebro 虽然“有点真实”和“有点虚假”与呃,真相并不太远,因为“x
是真实的”意味着bool(x) == True
,但不一定是x == True
.【参考方案2】:
有问题的行验证密码是'truthy',并且它与预定义的密码正则表达式匹配。
下面是它的分解方式:
如果password
是'falsey',函数返回password
。
如果密码为'truthy',但密码与密码正则表达式不匹配,则函数返回None
。
如果存在“真实”密码,并且与正则表达式匹配,则为 match object is returned。
and
运算符是“短路”运算符;如果第一个值是 'truthy',则返回第二个值。否则,它返回第一个值。
您可以查看this page 以了解在 python 中哪些类型的东西是“真实的”。
【讨论】:
“truthy”和“falsey”......呃......“测试为真”和“测试为假”怎么样? @LennartRegebro 这是因为它们并不是真正的True
布尔值,如果在布尔上下文中使用它们只是碰巧评估为 True。查看我的答案,了解使用字符串的布尔表达式示例。
'truthy' 和 'falsey' 是谈论这些事情的方式,也是描述性的。 'foo' 是真实的,但 'foo' != True。 '' 是假的,但 '' != 假的。
我以前从未听说过,我已经讨厌它了。这听起来像“不假但几乎”,这是假的。 :-) 这不是模糊逻辑。
在你的第三点,如果第一个值是-truthy-,那么它返回第二个值。【参考方案3】:
你只需要知道:
-
Python 中的空字符串计算结果为
False
(also None
, empty lists, and other "zero" types)。
布尔表达式经过称为short-circuit evaluation 的优化
因此,
a = '1'
print('' and a)
... 打印空字符串,因为它是 False,表达式永远不会是 True
,并且第二部分(a
)甚至都不会被计算。
和
a = '1'
print('' or a)
打印'1'
,因为空字符串为False,所以必须对第二部分求值以给出表达式的结果。
【讨论】:
以上是关于这个“and”语句实际上在返回中做了啥?的主要内容,如果未能解决你的问题,请参考以下文章
apply_filters(...) 实际上在 WordPress 中做了啥?