这个"和"声明实际上在回报中做了什么?

Mik*_*ter 10 python boolean return object

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

def valid_password(self, password):
        PASS_RE = re.compile(r'^.{6,128}$')
        return password and PASS_RE.match(password)
Run Code Online (Sandbox Code Playgroud)

进一步下载代码......

if not self.valid_password(self.password):
    params['error_password'] = "Please enter a valid password."
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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

rmu*_*unn 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
Run Code Online (Sandbox Code Playgroud)

使用"和",会发生同样的事情:首先检查第一个操作数,如果它是"假",则Python永远不会检查第二个操作数.如果第一个操作数是"truthy",那么Python返回第二个操作数,无论它是什么:

>>> 2 and 3
3
>>> 0 and 3
0
>>> 3 and 0
0
>>> 3 and []
[]
>>> 0 and []
0
Run Code Online (Sandbox Code Playgroud)

现在让我们谈谈"真实性"和"虚假性".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
[]
Run Code Online (Sandbox Code Playgroud)

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

>>> 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
Run Code Online (Sandbox Code Playgroud)

了解短路功能如何and帮助我们避免追溯?这就是这个功能正在发生的事情.

  • @LennartRegebro虽然"有点真实"和"有点虚假"离呃真相并不太远,因为"`x`是真的"暗示`bool(x)== True`但不一定是`x == True `. (4认同)
  • 事实上,其他答案中恰好有一半是正确的.所以这个答案是*不正确的*它声称大多数其他答案都不正确.我仍然不喜欢"真实"和"虚假",因为它暗示他们"有点真实"或"有点虚假". (2认同)

And*_*rew 7

相关行验证密码是"真实的",并且它与预定义的密码正则表达式匹配.

以下是它如何分解:

  • password如果password'falsey',则函数返回.

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

  • 如果存在'truthy'密码,并且它与正则表达式匹配,则返回匹配对象.

所述and操作员是一个"短路"运算符; 如果第一个值为'truthy',则返回第二个值.否则,它返回第一个值.

你可以查看这个页面,看看python中有什么类型的东西是"真实的".

  • 'truthy'和'falsey'是这些事情的讨论方式,也是描述性的.'foo'是真的,但是'foo'!=真的.''是假的,但''!=错. (6认同)
  • @LennartRegebro是因为它们不是真正的'True`布尔值,如果在布尔上下文中使用它们,它们恰好会被评估为True.查看我的答案,了解使用字符串的布尔表达式示例. (2认同)

Eli*_*les 5

你只需要知道:

  1. Python中的空字符串求值为False(还有None空列表和其他"零"类型).
  2. 布尔表达式受到称为短路评估的优化

因此,

a = '1'
print('' and a)
Run Code Online (Sandbox Code Playgroud)

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

a = '1'
print('' or a)
Run Code Online (Sandbox Code Playgroud)

print '1',因为空字符串为False,必须对第二部分进行求值以给出表达式的结果.