我试图更好地理解下面的python代码以及作者为什么在返回时使用了“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."
我已经尝试检查返回给调用者的结果对象,但是我仍然不完全理解它是如何工作的。
似乎这会将密码返回给调用者以及密码是否有效的布尔值,但我不明白调用函数如何检查对象的bool?这是我错过的关于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。
答案 0 :(得分:16)
在Python中,and
和or
都将返回其中一个操作数。使用or
,Python检查第一个操作数,如果它是一个“truthy”值(稍后更真实),它返回第一个值而不检查第二个(这称为布尔快捷方式评估,它可以是重要)。如果第一个是“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
使用“和”,会发生同样的事情:首先检查第一个操作数,如果它是“falsey”,则Python永远不会检查第二个操作数。如果第一个操作数是“truthy”,那么Python返回第二个操作数,无论它是什么:
>>> 2 and 3
3
>>> 0 and 3
0
>>> 3 and 0
0
>>> 3 and []
[]
>>> 0 and []
0
现在让我们谈谈“真实性”和“虚假性”。 Python使用以下规则来评估布尔上下文中的内容:
像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
的短路功能如何帮助我们避免追溯?这就是这个功能正在发生的事情。
答案 1 :(得分:7)
有问题的行验证密码是'truthy',并且它与预定义的密码正则表达式匹配。
以下是它如何分解:
如果password
为'falsey',则该函数返回password
。
如果密码为'truthy',但密码与密码正则表达式不匹配,则该函数返回None
。
如果有“真实”密码且与正则表达式匹配,则为match object is returned。
and
运算符是“短路”运算符;如果第一个值为'truthy',则返回第二个值。否则,它返回第一个值。
您可以查看this page以查看python中“truthy”的内容类型。
答案 2 :(得分:5)
你只需知道:
False
(also None
, empty lists, and other "zero" types)。因此,
a = '1'
print('' and a)
...打印空字符串,因为它是False,表达式永远不会是True
,而第二部分(a
)永远不会被评估。
和
a = '1'
print('' or a)
打印'1'
,因为空字符串为False,必须对第二部分进行求值以给出表达式的结果。