的是'关键字在Python中是如何实现的?

70 投票
11 回答
46992 浏览
提问于 2025-04-15 23:38

... is 这个关键词可以用来判断字符串是否相等。

>>> s = 'str'
>>> s is 'str'
True
>>> s is 'st'
False

我试过 __is__()__eq__(),但都没有成功。

>>> class MyString:
...   def __init__(self):
...     self.s = 'string'
...   def __is__(self, s):
...     return self.s == s
...
>>>
>>>
>>> m = MyString()
>>> m is 'ss'
False
>>> m is 'string' # <--- Expected to work
False
>>>
>>> class MyString:
...   def __init__(self):
...     self.s = 'string'
...   def __eq__(self, s):
...     return self.s == s
...
>>>
>>> m = MyString()
>>> m is 'ss'
False
>>> m is 'string' # <--- Expected to work, but again failed
False
>>>

11 个回答

16

Python中的is关键字用来检查两个对象是否是同一个对象。你不应该用它来判断字符串是否相等。虽然它看起来经常能用,但其实是因为Python在处理字符串时会做一种叫“驻留”的优化。简单来说,就是相同的字符串会被存储在一个内部的列表中,指向同一个对象。(这之所以可行,是因为Python中的字符串是不可变的。)

不过,像所有实现细节一样,你不应该依赖这个特性。如果你想判断两个字符串是否相等,应该使用==运算符。如果你真的想检查两个对象是否是同一个对象,那就用is,但我很难想出有什么情况下你需要关心字符串对象的身份。可惜的是,你不能指望两个字符串在某种情况下会“故意”指向同一个对象,因为之前提到的驻留机制。

26

is 操作符的作用就像是比较两个对象的唯一标识符,也就是它们的 id(x) 值。举个例子:

>>> s1 = 'str'
>>> s2 = 'str'
>>> s1 is s2
True
>>> id(s1)
4564468760
>>> id(s2)
4564468760
>>> id(s1) == id(s2)  # equivalent to `s1 is s2`
True

目前,id 是通过指针来进行比较的。所以你不能重载 is 操作符,也就是说不能改变它的默认行为。根据我所知道的,你也不能重载 id

所以,答案就是不可以。这在 Python 中比较少见,但就是这样。

143

is 来测试字符串只有在字符串被“内部化”的情况下才有效。除非你非常清楚自己在做什么,并且明确地进行了字符串的“内部化”,否则你绝对不应该在字符串上使用 is

is 是用来检查身份的,而不是相等性。这意味着 Python 只是比较对象在内存中的地址。is 基本上是在回答“我是否有两个名字指向同一个对象?” - 如果把它用来做其他事情就没有意义了。

举个例子,("a" * 100) is ("a" * 100) 的结果是。通常情况下,Python 会把每个字符串写入不同的内存位置,只有在字符串是字面量时,才会进行“内部化”。

撰写回答