Python解释器字符串池优化

Car*_*ans 6 python string string-pool

在看到这个问题它的重复的问题仍然存在对我来说.

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

a = "ab"
b = "ab"

a == b
Run Code Online (Sandbox Code Playgroud)

我得到True.这里的问题是为什么会发生这种情况:

a = "ab"
b = "ab"
a is b # Returns True
Run Code Online (Sandbox Code Playgroud)

所以我做了我的研究,我找到了这个.答案说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??
Run Code Online (Sandbox Code Playgroud)

所以对于某些字符来说,字符串池不起作用.我在这个例子中使用了Python 2.7.6,所以我认为这将在Python 3中修复.但是在Python 3中尝试相同的例子后,会出现相同的结果.

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


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

Leo*_*eon 5

你的问题是一个更普遍的问题的重复" python什么时候选择实习字符串 ",正确的答案字符串实习是特定于实现的.

本文非常好地描述了CPython 2.7.7中的字符串实习:Python字符串实习的内部结构.其中的信息可以解释您的示例.

该字符串的原因"ab""a_b"被拘留,而"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;
}
Run Code Online (Sandbox Code Playgroud)

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