为什么 Python 3 和 C 中的 if 语句会产生不同的结果?

Why different results from an if-statement in Python 3 and C?

我希望打印的值是“200!”和“404!”在 Python3.4。但我得到的结果是“200!”和 "else!".

我做了个怪脸——在C里又试了一遍,C里的结果和Python3不一样。为什么?

Python3.4码

def chk(s): 
    if s is 200:
        print('200!')
    elif s is 404:
        print('404!')
    else:
        print('else!')

chk(200)
chk(404)

Python3.4 代码结果

200!
else!

C代码

#include <stdio.h>

void chk(int s) {
    if (s == 200)
        printf("200!");
    else if (s == 404)
        printf("404!");
    else
        printf("else!");
}

int main(void) {
    chk(200);
    chk(404);
    return 0;
}

C码结果

200!404!

is 本身并不意味着 "equal"。它实际上意味着 "occupies the same location in memory." 此外,在数字上使用 is 有奇怪的行为,这取决于您使用的 python 的版本。 (我的意思是 Cpython vs Jpython vs pypy vs....)所以不要使用它,使用 == 作为数字。

def chk(s): 
    if s == 200:
        print('200!')
    elif s == 404:
        print('404!')
    else:
        print('else!')

chk(200)
chk(404)

(如果您想了解为什么 200 is 200 产生 True404 is 404 产生 False 的更多细节:基本上,从 -5 到 [=19 的数字=] 被缓存在 CPython 中。他们每个人都有自己的小内存槽,如果他们被分配给一个变量,CPython 只是将变量指向预先分配的内存槽。对于超出该范围的数字则不是这种情况。如果需要这些,CPython 将找到一个空的内存槽,将数字放在那里,并将变量指向它。如果将 404 分配给两个单独的变量,则内存中有两个单独的 404 整数。)

更多:

When to use is, when to use ==.

CPython, is, and why you should never use it with numbers

is 基本上比较对象的 身份 。请注意 Python names 只是对实际对象的引用。所以,C 等价物基本上是:

int k = 200, *i;
const int c = 200;

i = &k;

if ( i == &c )
    // fails, but *i == c is true
    .... 

因此,您不应该使用 is 来比较 equality 的值,而应该只比较 identity 的值。最重要的用例是:

if val is None:
    ...

因为正好有一个None对象。

if val == None:
    ...

OTOH 将受到强制规则的约束,因此对于其他各种情况也是如此。

阅读 here(搜索有关 is 的段落)和脚注以获取详细信息。