68

...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
>>>
4

11 回答 11

141

is仅当字符串被实习时测试字符串才有效。除非你真的知道你在做什么并且明确地把你永远不应该在字符串上使用的字符串。is

is测试身份,而不是平等。这意味着 Python 只是比较对象所在的内存地址。is基本上回答了“同一个对象有两个名称吗?”这个问题。- 重载没有任何意义。

例如,("a" * 100) is ("a" * 100)False。通常 Python 将每个字符串写入不同的内存位置,实习主要发生在字符串文字上。

于 2010-06-07T08:21:44.777 回答
24

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自己,AFAIK你也不能超载id

所以,你不能。在 python 中不寻常,但它确实存在。

于 2010-06-07T08:27:04.423 回答
16

Pythonis关键字测试对象身份。你不应该用它来测试字符串是否相等。它似乎经常工作,因为 Python 实现,就像许多非常高级的语言一样,执行字符串的“实习”。也就是说,字符串文字和值在内部保存在一个散列列表中,而那些相同的则呈现为对同一对象的引用。(这是可能的,因为 Python 字符串是不可变的)。

但是,与任何实现细节一样,您不应依赖于此。如果要测试是否相等,请使用 == 运算符。如果你真的想测试对象身份,那么使用is--- 我很难想出一个你应该关心字符串对象身份的案例。不幸的是,由于上述实习,您不能指望两个字符串是否以某种方式“故意”相同的对象引用。

于 2010-06-07T08:27:41.927 回答
10

关键字比较is对象(或者更确切地说,比较两个引用是否指向同一个对象)。

我认为,这就是为什么没有提供您自己的实现的机制的原因。

它有时会在字符串上起作用,因为 Python 会“巧妙地”存储字符串,这样当您创建两个相同的字符串时,它们就会存储在一个对象中。

>>> a = "string"
>>> b = "string"
>>> a is b
True
>>> c = "str"+"ing"
>>> a is c
True

您可以希望在一个简单的“复制”示例中看到参考与数据比较:

>>> a = {"a":1}
>>> b = a
>>> c = a.copy()
>>> a is b
True
>>> a is c
False
于 2010-06-07T08:26:21.897 回答
5

如果您不怕弄乱字节码,您可以拦截并COMPARE_OP使用8 ("is")参数进行修补,以在被比较的对象上调用您的钩子函数。查看dis模块文档以了解入门。

如果__builtin__.id()有人会id(a) == id(b)代替a is b.

于 2010-10-12T03:03:09.417 回答
3

'is' 比较对象身份,而 == 比较值。

例子:

a=[1,2]
b=[1,2]
#a==b returns True
#a is b returns False

p=q=[1,2]
#p==q returns True
#p is q returns True
于 2017-03-09T13:35:12.787 回答
2

当字符串以“-”开头时,无法将字符串变量与字符串值和两个字符串变量进行比较。我的 Python 版本是 2.6.6

>>> s = '-hi'
>>> s is '-hi'
False 
>>> s = '-hi'
>>> k = '-hi'
>>> s is k 
False
>>> '-hi' is '-hi'
True
于 2011-04-07T15:53:34.977 回答
1

您不能重载is运算符。您要重载的是==运算符。这可以通过__eq__在类中定义一个方法来完成。

于 2011-06-15T04:24:14.287 回答
1

您正在使用身份比较。==可能是你想要的。例外情况是当您想要检查一个项目和另一个项目是否是完全相同的对象并且位于相同的内存位置时。在您的示例中,项目不一样,因为一个项目的类型(my_string)与另一个项目(字符串)不同。此外,没有 someclass 这样的东西。__is__在 python 中(当然,除非你自己把它放在那里)。如果有的话,将对象与is进行比较是不可靠的,只是简单地比较内存位置。

当我第一次遇到is关键字时,它也让我感到困惑。我原以为和 == 没有什么不同。他们从解释器对许多对象产生了相同的输出。这种类型的假设实际上正是...的用途。它是 python 的等价物“嘿,不要误会这两个对象。它们是不同的。”,这基本上是 [不管是谁让我理顺] 所说的。措辞大不相同,但一点==另一点。

对于一些有用的示例和一些文本来帮助解决有时令人困惑的差异,请访问由“Danny Yoo”编写的来自 python.org 邮件主机的文档

或者,如果它处于离线状态,请使用我用它的主体制作的未列出的 pastebin 。

万一他们,在大约 20 个左右的蓝月亮(蓝月亮是一个真实的事件)中,都下降了,我将引用代码示例

###
>>> my_name = "danny"
>>> your_name = "ian"
>>> my_name == your_name
0                #or False
###

###
>>> my_name[1:3] == your_name[1:3]
1    #or True
###

###
>>> my_name[1:3] is your_name[1:3]
0
###
于 2013-01-04T18:01:53.867 回答
0

在比较对象时,使用is关键字很容易出现断言错误。例如,对象ab可能拥有相同的值并共享相同的内存地址。因此,做一个

>>> a == b

将评估为

True

但如果

>>> a is b

评估为

False

你应该检查一下

>>> type(a)

>>> type(b)

这些可能是不同的,也是失败的原因。

于 2017-02-07T11:17:58.587 回答
0

因为字符串实习,这看起来很奇怪:

a = 'hello'
'hello' is a  #True

b= 'hel-lo'
'hel-lo' is b #False
于 2020-08-01T14:41:12.083 回答