python中is和==的区别

前提:变量、内存地址

>>> a = "test"     #a是变量名,变量的值是"test"
>>> id(a)    #变量的内存地址是2364845921088,id函数返回变量的内存地址
2364845921088

is:比较的是两个对象的id值是否相等,也就是比较俩对象是否为同一个实例对象,是否指向同一个内存地址。

int数据类型:

>>> m = 257
>>> id(m)
2364844528784
>>> m1 = 257
>>> id(m1)
2364844529328

>>> m is m1
False

>>> m = 3//2
>>> n = 1
>>> m is n
True


>>> m3 = 256
>>> id(m3)
1896844272
>>> m4 = 256
>>> id(m4)
1896844272

>>> m3 is m4
True

出于对性能的考虑,Python内部做了很多的优化工作,对于整数对象,Python把一些频繁使用的整数对象缓存起来,保存到一个叫small_ints的链表中,在Python的整个生命周期内,任何需要引用这些整数对象的地方,都不再重新创建新的对象,而是直接引用缓存中的对象。Python把这些可能频繁使用的整数对象规定在范围[-5, 256]之间的小对象放在small_ints中,但凡是需要用些小整数时,就从这里面取,不再去临时创建新的对象。因为257不再小整数范围内,因此尽管a和b的值是一样,但是他们在Python内部却是以两个独立的对象存在的,各自为政,互不干涉。

>>> x = 257
>>> def fun():
...     y = 257
...     z = 257
...     print(y is z)
...     print(y is x)
...
>>> fun()
True
False

Python程序由代码块构成,代码块作为程序的一个最小基本单位来执行。一个模块文件、一个函数体、一个类、交互式命令中的单行代码都叫做一个代码块。在上面这段代码中,由两个代码块构成,c = 257作为一个代码块,函数foo作为另外一个代码块。Python内部为了将性能进一步的提高,凡是在一个代码块中创建的整数对象,如果存在一个值与其相同的对象于该代码块中了,那么就直接引用,否则创建一个新的对象出来。Python出于对性能的考虑,但凡是不可变对象,在同一个代码块中的对象,只有是值相同的对象,就不会重复创建,而是直接引用已经存在的对象因此,不仅是整数对象,还有字符串对象也遵循同样的原则。所以 a is b就理所当然的返回True了,而c和a不在同一个代码块中,因此在Python内部创建了两个值都是257的对象。

两点结论:

1、小整数对象[-5,256]是全局解释器范围内被重复使用,永远不会被GC回收。需要注意的是,这仅仅是在命令行中执行,而在Pycharm或者保存为文件执行,结果是不一样的,这是因为解释器做了一部分优化。

2、同一个代码块中的不可变对象,只要值是相等的就不会重复创建新的对象。

 

str数据类型:

想要true结果,字符串中不能有特殊字符

>>> stringa = "chang222"
>>> stringb = "chang222"
>>> stringa is stringb
True
>>> stringa = "chang444"
>>> stringb = "chang444"
>>> stringa is stringb
True
>>> stringa = "chang+@"
>>> stringb = "chang+@"
>>> stringa is stringb
False

 

py文件:

只要内容一样,内存就一样

 

切片:

>>> a = [1,2,3]
>>> b = a[:]  # b通过切片重新分配了对象
>>> b is a
False
>>> id(a)
2364845926920
>>> id(b)
2364845906120
>>> a == b
True

新建对象之后,b 和 a 指向了不同的内存,所以 b is a 的结果为False,而 b==a的结果为True。在这里,b[0] is a[0] 的结果是True。因为切片拷贝是浅拷贝,列表中的元素并未重新创建。

、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、

==:比较的是两个对象的内容是否相等,内存地址可以不一样,默认会调用对象的__eq__()方法。

>>> a == b
True
>>> a = [1,2,3]
>>> b = a  # a的引用赋值给b,在内存中指向了同一个对象 
>>> b is a
True
>>> b == a
True

b和a的内存地址是相同的,它们指向同一块内存,因而 is 和 == 的结果都为True。这是因为直接赋值都是赋值的引用。

is和==区别:

  1. is 与 == 相比有一个比较大的优势,就是计算速度快,因为它不能重载,不用进行特殊的函数调用,少了函数调用的开销而直接比较两个整数 id。而 a == b 则是等同于a.__eq__(b)。继承自 object 的 __eq__ 方法比较两个对象的id,结果与 is 一样。但是多数Python的对象会覆盖object的 __eq__方法,而定义内容的相关比较,所以比较的是对象属性的值。
  2. is 比较两个对象的 id 值是否相等,是否指向同一个内存地址;== 比较的是两个对象的内容是否相等,值是否相等;
  3. 小整数对象[-5,256]在全局解释器范围内被放入缓存供重复使用;
  4. is 运算符比 == 效率高,在变量和None进行比较时,应该使用 is。在变量和单例值之间比较时,应该使用 is。目前,最常使用 is 的地方是判断对象是不是 None。a is None。判断不是None的写法为a is not None。

 

参考链接:

https://www.cnblogs.com/lilz/p/9410319.html

https://www.cnblogs.com/tianqianlan/p/9438380.html

多谢。

你可能感兴趣的:(python)