10

我试图更好地理解以下 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."

我已经尝试检查返回给调用者的结果对象,但是我仍然不完全理解它是如何工作的。

似乎这会将密码返回给调用者以及密码是否有效的布尔值,但是我不明白调用函数如何检查对象的布尔值?这是我错过的关于 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。

4

3 回答 3

16

在 Python 中,两者andor都将返回它们的操作数之一。使用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帮助我们避免回溯?这就是这个函数中发生的事情。

于 2013-06-25T03:23:43.210 回答
7

有问题的行验证密码是“真实的”并且它与预定义的密码正则表达式匹配。

以下是它的分解方式:

  • password如果password'falsey',该函数返回。

  • 如果密码是 'truthy',但密码与密码正则表达式不匹配,则函数返回None.

  • 如果有一个“真实”密码,并且它与正则表达式匹配,则返回匹配对象

and算子是“短路”算子;如果第一个值是 'truthy',则返回第二个值。否则,它返回第一个值。

您可以查看此页面以查看 python 中哪些类型的东西是“真实的”。

于 2013-06-25T03:01:42.677 回答
5

你只需要知道:

  1. Python 中的空字符串计算结果为False还有None,空列表和其他“零”类型)。
  2. 布尔表达式受到称为短路评估的优化

所以,

a = '1'
print('' and a)

... 打印空字符串,因为它是 False,表达式永远不会是True,第二部分 (the a) 甚至不会被评估。

a = '1'
print('' or a)

prints '1',因为空字符串为 False,所以必须计算第二部分以给出表达式的结果。

于 2013-06-25T03:11:29.777 回答