6

在看到这个问题及其重复后,我仍然有一个问题。

我得到什么is==做什么以及为什么如果我跑步

a = "ab"
b = "ab"

a == b

我明白了True。这里的问题是为什么会发生这种情况:

a = "ab"
b = "ab"
a is b # Returns True

所以我做了我的研究,我发现了这个。答案说 Python 解释器使用字符串池。因此,如果它看到两个字符串相同,它会将相同的字符串分配给id新的字符串以进行优化。

直到这里一切都很好并且得到了回答。我真正的问题是为什么这种池只发生在某些字符串上。这是一个例子:

a = "ab"
b = "ab"
a is b # Returns True, as expected knowing Interpreter uses string pooling

a = "a_b"
b = "a_b"
a is b # Returns True, again, as expected knowing Interpreter uses string pooling

a = "a b"
b = "a b"
a is b # Returns False, why??

a = "a-b"
b = "a-b"
a is b # Returns False, WHY??

因此,对于某些字符,字符串池似乎不起作用。我在这个示例中使用了 Python 2.7.6,所以我认为这将在 Python 3 中得到修复。但是在 Python 3 中尝试了相同的示例后,出现了相同的结果。

问题:为什么没有针对此示例优化字符串池?对 Python 进行优化不是更好吗?


编辑:如果我运行"a b" is "a b"返回True。问题是为什么使用变量它会False为某些字符返回而其他字符True

4

1 回答 1

5

您的问题与更一般的问题“ python 何时选择实习字符串”重复,正确答案字符串实习是特定于实现的

这篇文章很好地描述了 CPython 2.7.7 中的字符串实习:Python 字符串实习的内部。其中的信息可以解释您的示例。

字符串"ab""a_b"被实习的原因是,前者看起来像 python 标识符,"a b""a-b"后者不像。

自然,实习每个字符串都会产生运行时成本。因此解释器必须决定给定的字符串是否值得实习。由于 Python 程序中使用的标识符名称作为字符串嵌入程序的字节码中,因此类似标识符的字符串更有可能从实习中受益。

上述文章的简短摘录:

该函数all_name_chars排除不是由 ascii 字母、数字或下划线组成的字符串,即看起来像标识符的字符串:

#define NAME_CHARS \
    "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"

/* all_name_chars(s): true iff all chars in s are valid NAME_CHARS */

static int
all_name_chars(unsigned char *s)
{
    static char ok_name_char[256];
    static unsigned char *name_chars = (unsigned char *)NAME_CHARS;

    if (ok_name_char[*name_chars] == 0) {
        unsigned char *p;
        for (p = name_chars; *p; p++)
            ok_name_char[*p] = 1;
    }
    while (*s) {
        if (ok_name_char[*s++] == 0)
            return 0;
    }
    return 1;
}

考虑到所有这些解释,我们现在理解了为什么'foo!' is 'foo!'评估为False'foo' is 'foo'评估为 True

于 2017-02-21T10:18:47.290 回答