Python 为什么'None is None is None'返回True?

Python 为什么'None is None is None'返回True?,python,python-3.x,python-2.7,Python,Python 3.x,Python 2.7,今天,在一次采访中,首席技术官问了我一个看似简单的问题 此语句返回什么内容?: None is None is None 我认为Python执行了第一个操作None is None,并将返回True。之后,它将比较True是否为None,这将返回False。但是,令我惊讶的是,正确的答案是正确的。我试图找到这个问题的答案,但经过几天的搜索,我什么也没找到。有人能解释为什么会发生这种情况吗?是一个比较运算符,: 相当于 (a is b) and (b is c) 正如一些人评论的那样,Pyth

今天,在一次采访中,首席技术官问了我一个看似简单的问题

此语句返回什么内容?:

None is None is None

我认为Python执行了第一个操作
None is None
,并将返回
True
。之后,它将比较
True是否为None
,这将返回
False
。但是,令我惊讶的是,正确的答案是
正确的
。我试图找到这个问题的答案,但经过几天的搜索,我什么也没找到。有人能解释为什么会发生这种情况吗?

是一个比较运算符,

相当于

(a is b) and (b is c)
正如一些人评论的那样,Python比较可以链接起来

为了便于解释,在链接时,Python实际上是表达式

这背后的基本原理是,像
a
这样的表达式具有数学中常规的解释。因此,您的特定表达式
None is None is None
在涉及identi运算符的情况下会出现混淆

因此,基本上,这将转化为:

(None is None) and (None is None)
这显然是正确的

这里是Python中的另一个示例

进一步信息

(10 > x) and (x > 2)
特别是因为这是一个面试问题,需要注意的是,这并不是所有语言的共同行为

正如我链接的文档中所述

与C不同,Python中的所有比较操作都具有相同的优先级, 它比任何算术、移位或按位运算都要低 手术

<> P> >让我们考虑<代码> 10 > x> 2 < /Cord>表达式(因为<代码> 运算符在C中无效)。 C的翻译(因为)

Python的翻译

(10 > x) and (x > 2)

字节码显示此处正在执行两个比较,中间部分重复:

>>> import dis
>>> def a():
...     return None is None is None
... 
>>> dis.dis(a)
  2           0 LOAD_CONST               0 (None)
              3 LOAD_CONST               0 (None)
              6 DUP_TOP
              7 ROT_THREE
              8 COMPARE_OP               8 (is)
             11 JUMP_IF_FALSE_OR_POP    21
             14 LOAD_CONST               0 (None)
             17 COMPARE_OP               8 (is)
             20 RETURN_VALUE
        >>   21 ROT_TWO
             22 POP_TOP
             23 RETURN_VALUE
正如本文中所述,这是因为这些运营商紧密相连


a op b op c
将被转换为
a op b和b op c
(注意
b
在字节码中重复,如上所示)

Python比较运算符链
None is None is None
相当于
None is None and None is None
。要获得您期望的行为,您必须使用括号:
如果(None is None)是None
。尽管很有趣。我从来不知道会发生这种情况,如果知道
是什么
操作符,我也会期待同样的事情…@SilvioMayolo这真的是重复的吗?这不是同一个问题。答案是一样的,但问题不是。对于这类问题,我喜欢这个答案,因为它解释了行为背后的基本原理:像aNone is None is None是一种特殊的误导性陈述,遵循这种逻辑,因为不涉及数学。虽然确实不涉及数学,但结果仍然符合口语用法。例如,“傻瓜是傻瓜是傻瓜”可以用来强调,而“傻瓜是傻瓜是傻瓜”则意味着这三个术语之间是等价的。@IMSoP你是对的,数学不是一个好术语。看到我的答案了吗?我的意思是使用了identity运算符,这与使用类似于
的比较运算符时的相同行为相比确实令人困惑。我不确定使用identity运算符会有多少惊喜;它们只是另一种比较。正如我所说,在英语中我们会用“是”这个词,一个数学家可能会写出
x=y=z
,或者
x≡ Y≡ z
,等等。我觉得这很奇怪,因为编程语言通常没有这样的运算符。请注意,赋值不是同一语义的比较。具体而言,
a=b=c
的评估方法与
a是b是c
或类似方法不同<代码>a=b=c从右向左运行。而
a comp b comp c
被转换为
a comp b
b comp c
a=b=c
被转换成
b=c;a=b
@shuttle87是。。我只是为后面的示例编写了
a=b=c=None
(10 > x) and (x > 2)
>>> import dis
>>> def a():
...     return None is None is None
... 
>>> dis.dis(a)
  2           0 LOAD_CONST               0 (None)
              3 LOAD_CONST               0 (None)
              6 DUP_TOP
              7 ROT_THREE
              8 COMPARE_OP               8 (is)
             11 JUMP_IF_FALSE_OR_POP    21
             14 LOAD_CONST               0 (None)
             17 COMPARE_OP               8 (is)
             20 RETURN_VALUE
        >>   21 ROT_TWO
             22 POP_TOP
             23 RETURN_VALUE