这个“和"是什么?声明中究竟在做什么?

2022-01-19 00:00:00 python return object boolean

问题描述

我试图更好地理解以下python代码以及作者为什么在return中使用AND"语句.

I am trying to get a better understanding of the following python code and why the author has used the "AND" statement in the return.

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."

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

I've tried inspecting the resulting object that gets handed back to the caller, however I still don't entirely understand how it works.

似乎这会将密码返回给调用者以及密码是否有效的布尔值,但是我不明白调用函数如何检查对象的布尔值?这是我错过的关于 Python 的基本知识吗?

It seems like this returns the password back to the caller and a boolean of whether or not the password is valid, however I don't understand how the calling function can check the bool of an object? Is this something basic about Python that I've missed?

在这个例子旁边还有另一个类似用法的例子,但是它使用或"语句,这对我来说更令人困惑:

There is another example of a similar usage next to this one however it uses the "or" statement which to me is even more confusing:

def valid_email(self, email):
    EMAIL_RE  = re.compile(r'^[S]+@[S]+.[S]+$')
    return not email or EMAIL_RE.match(email)

任何关于这里到底发生了什么的建议将不胜感激.该代码可以正常工作并执行您期望它执行的操作,根据正则表达式验证输入并返回 True 或 False,但是我真的很想了解它是这样写的,而不是简单地返回 bool.

Any advice on exactly what is going on here would be greatly appreciated. The code works and does what you would expect it to do, validates the input against a regular expression and returns True or False, however I would really like to understand what it was written like this and not simply returning the bool.


解决方案

在 Python 中,andor 都将返回它们的操作数之一.使用 or,Python 会检查第一个操作数,如果它是真实"值(稍后将详细介绍真实性),它会返回第一个值而不检查第二个值(这称为布尔快捷评估,并且这可能很重要).如果第一个是falsey",那么 Python 返回第二个操作数,不管它是什么:

In Python, both and and or will return one of their operands. With or, Python checks the first operand and, if it is a "truthy" value (more on truthiness later), it returns the first value without checking the second (this is called Boolean shortcut evaluation, and it can be important). If the first is "falsey", then Python returns the second operand, no matter what it is:

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 返回第二个操作数,不管它是什么:

With "and", much the same thing happens: the first operand is checked first, and if it is "falsey", then Python never checks the second operand. If the first operand is "truthy", then Python returns the second operand, no matter what it is:

>>> 2 and 3
3
>>> 0 and 3
0
>>> 3 and 0
0
>>> 3 and []
[]
>>> 0 and []
0

现在我们来谈谈真"和假".Python 使用以下规则在布尔上下文中评估事物:

Now let's talk about "truthiness" and "falsiness". Python uses the following rules for evaluating things in a Boolean context:

  • 以下值为falsey":False、None、0(零)、[](空列表)、()(空元组)、{}(空字典)、空集、"(空字符串)
  • 其他一切都是真实的"

所以像 password 和 PASS_RE.match(password) 这样的东西正在利用 Python 的短路评估.如果 password 为 None,则 and 运算符将只返回 None 并且永远不会计算后半部分.这很好,因为 PASS_RE.match(None) 会引发异常.观看:

So something like password and PASS_RE.match(password) is taking advantage of Python's short-circuit evaluation. If password is None, then the and operator will just return None and never evaluate the second half. Which is good, because PASS_RE.match(None) would have thrown an exception. Watch this:

>>> 3 or []
3
>>> [] or 3
3
>>> 0 or []
[]
>>> [] or 0
0
>>> 0 and []
0
>>> [] and 0
[]

看看短路是如何工作的?现在看这个:

See how the short-circuiting is working? Now watch this:

>>> 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

了解 的短路特性如何帮助我们避免回溯?这就是这个函数中发生的事情.

See how the short-circuiting feature of and helped us avoid a traceback? That's what's going on in this function.

相关文章