在Python中如何实现'is'关键字?
…可以用于string中的相等的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 >>>
使用string进行testing仅在string被执行时有效。 除非你真的知道你在做什么,并且明确地实现了你不应该使用string的string。
is
testing身份 ,而不是平等 。 这意味着Python只是比较一个对象所在的内存地址。基本上回答了这个问题:“我对同一个对象有两个名字吗? – 超载,这是没有意义的。
例如, ("a" * 100) is ("a" * 100)
是False 。 通常Python将每个string写入不同的内存位置,实际上主要发生在string文字上。
is
运算符等同于比较id(x)
值。 目前使用id
作为比较来实现。 所以你不能重载本身,而AFAIK你也不能重载id
。
所以,你不能。 在Python中是不寻常的,但在那里。
Python is
关键字testing对象标识。 你不应该用它来testingstring是否相等。 它似乎经常工作,因为像许多高级语言的Python实现一样,执行string“interning”。 也就是说,string文字和值被内部保存在散列表中,而那些相同的文字和值被渲染为对同一对象的引用。 (这是可能的,因为Pythonstring是不可变的)。
但是,与任何实现细节一样,您不应该依赖于此。 如果你想testing的平等使用==运算符。 如果你真的想testing对象的身份然后使用—我会很难提出一个案例,你应该关心string对象的身份。 不幸的是,你不能指望两个string是否由于上述的实习而以某种方式“故意”相同的对象引用。
is
关键字比较对象(或者比较两个引用是否是同一个对象)。
我想,这就是为什么没有机制来提供你自己的实现。
它恰好在string上工作,因为Python巧妙地存储了string,这样当你创build两个相同的string时,它们被存储在一个对象中。
>>> 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
如果你不怕弄乱字节码,你可以用8 ("is")
参数拦截和修补COMPARE_OP
,以便在被比较的对象上调用钩子函数。 查看启动模块文档。
并且不要忘记拦截__builtin__.id()
如果有人做id(a) == id(b)
而不是a is b
。
当string以“ – ”开始时,无法将stringvariables与string值和两个stringvariables进行比较。 我的Python版本是2.6.6
>>> s = '-hi' >>> s is '-hi' False >>> s = '-hi' >>> k = '-hi' >>> s is k False >>> '-hi' is '-hi' True
你不能重载is
运算符。 你想要重载的是==
操作符。 这可以通过在类中定义__eq__
方法来完成。
你正在使用身份比较。 ==可能是你想要的。 这是一个例外,当你想要检查一个项目和另一个项目是否是相同的对象,并在相同的内存位置。 在你的例子中,这个项目是不一样的,因为一个是不同的types(my_string)比另一个(string)。 而且,没有某个类别的东西。 Python中的__is__
(除非你自己把它放在那里)。 如果存在的话,比较对象与is仅仅比较内存位置是不可靠的。
当我第一次遇到的关键字,它也困惑我。 我会认为是和==没有什么不同。 他们在解释器上产生了许多对象的相同输出。 这种types的假设实际上是 …的原因。 这是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 ###
“是”比较对象的身份,而==比较值。
例:
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
断言在比较对象时,用关键字很容易产生错误。 例如,对象a和b可能保持相同的值并共享相同的内存地址。 所以,做一个
>>> a == b
将要评估
True
但如果
>>> a is b
评估
False
你应该检查一下
>>> type(a)
和
>>> type(b)
这些可能是不同的,也是失败的原因。