Python字符串标识:`is`和`in`语句

Aar*_*hif 6 python string

我有一些问题让这个工作:

# Shortened for brevity
def _coerce_truth(word):
    TRUE_VALUES = ('true','1','yes')
    FALSE_VALUES = ('false','0','no')

    _word = word.lower().strip()
    print "t" in _word
    if _word in TRUE_VALUES:
        return True
    elif _word in FALSE_VALUES:
        return False
Run Code Online (Sandbox Code Playgroud)

我发现:

In [20]: "foo" is "Foo".lower()
Out[20]: False

In [21]: "foo" is "foo".lower()
Out[21]: False

In [22]: "foo" is "foo"
Out[22]: True

In [23]: "foo" is "foo".lower()
Out[23]: False
Run Code Online (Sandbox Code Playgroud)

为什么是这样?我理解身份与平等不同,但身份何时形成?False除非由于字符串的静态性质,否则声明22应该是id == eq.在这种情况下,我对陈述23感到困惑.

请提前解释并表示感谢.

mgi*_*son 6

问:"身份何时形成?"

A.创建对象时.

您所看到的实际上是Cpython的实现细节 - 它缓存小字符串并重用它们以提高效率.其他有趣的案例是:

"foo" is "foo".strip()  # True
"foo" is "foo"[:]       # True
Run Code Online (Sandbox Code Playgroud)

最终,我们看到的是字符串文字"foo"已被缓存.每次键入时"foo",都会在内存中引用相同的对象.但是,一些字符串方法将选择始终创建新对象(如.lower()),如果方法没有做任何更改(如.strip()),有些将巧妙地重用输入字符串.


这样做的一个好处是,如果指针比较为假,则可以通过指针比较(非常快)实现字符串相等,然后进行逐字符比较.如果指针比较为True,则可以避免逐个字符的比较.