首先看下面一段程序:
def test(): # example 1 a = 'hello' b = 'hello' print(a is b) # 输出True print(a == b) # 输出True # example 2 a = 'hello world' b = 'hello world' print(a is b) # 输出False print(a == b) # 输出True # example 3 a = [1, 2, 3] b = a print(a is b) # 输出True print(a == b) # 输出True
上面的输出结果为什么有的相同,有的不相同呢?
官方文档描述is为对象标示符(object identity),而==表示的是相等。is的作用是用来检查对象的标示符是否一致,也就是两个对象在内存中的位置是否一样,而==是用来检查两个对象是否相等。
我们来看一下下面的程序,检查每个对象的id
def test(): # example 1 a = 'hello' b = 'hello' print(id(a)) # 输出2378974396344 print(id(b)) # 输出2378974396344 print(a is b) # 输出True print(a == b) # 输出True # example 2 a = 'hello world' b = 'hello world' print(id(a)) # 输出2378974396344 print(id(b)) # 输出2033022437424 print(a is b) # 输出False print(a == b) # 输出True # example 3 a = [1, 2, 3] b = a print(id(a)) # 输出1641701071688 print(id(b)) # 输出1641701071688 print(a is b) # 输出True print(a == b) # 输出True
打印出id结果就很清晰了,只要a和b值相同,==结果输出True;只有id相同,is结果输出True。但是有一个问题,为什么example1的'hello' a is b就输出True,而example2的'hello world'就输出False。
这是因为前一种情况下Python的字符串驻留机制起了作用。对于较小的字符串,为了提高系统性能Python会保留其值的一个副本,当创建新的字符串的时候直接指向该副本即可。所以'hello'在内存中只有一个副本,a和b的id值相同,而'hello world'是长字符串,不驻留内存,Python中各自创建了对象来表示a和b,所以他们的值相同,但是id值不同。(有些编译器会对程序优化,所以is操作可能不同)。
实际python中None的比较,为什么是is None,而不是== None呢?
这是因为None在Python里是个单例对象,一个变量如果是None,它一定和None指向同一个内存地址。而==None背后调用的是__eq__,而__eq__可以被重载,下面是一个is not None但== None的例子
class Foo(object): def __eq__(self,other): return True f = Foo() print(f is None) # 输出False print(f == None) # 输出True上面==被重载,所以输出True。