Python对象的身份比较

作者: 无聊的IT | 来源:发表于2017-04-28 11:34 被阅读95次

相较于值的比较,Python也支持身份的比较。

身份比较运算符:

运算符 说明
is 结果为True,运算符两端是同一个对象,如果是False,则为不同对象。
is not 结果为True,运算符两端不是同一个对象,结果为False,则为同一个对象。

什么是身份比较

所谓身份比较,即判断两个或更多的不同名称的对象是否为同一个对象。

>>> a=2570
>>> b=2570
>>> a==b
True
>>> a is b
False

上面的例子中分别给变量a和b赋值整型数值257,通过对象值比较运算a==b,其结果是True,说明两个变量的值是相等的,但通过身份比较运算a is b,其结果却是False。说明,虽然两个变量的值虽然相等,但却并不是同一个对象

再看一个例子:

>>> a=b=2570
>>> a is b
True
>>> c=2570
>>> d=c
>>> c is d
True

上面的例子中同样是给不同名称的变量赋值,但其赋值方式跟第一个例子略有区别,此时通过身份比较运算符可以看出,其中变量a和变量b是同一个对象,变量c和变量d是同一个对象。

为什么会出现不同名称的对象会是同一个对象这种情况?

Python语言中对象赋值跟其他语言略有区别。
  比较通俗的理解是,在其他语言中是创建一个变量,然后把值赋给变量,变量值是依附于变量的。
  Python中是先创建一个值(对象),然后把不同的变量名称引用给这个值,相当于给这个值贴了不同名称的标签,变量名称是依附于变量值的。所以不同的变量名称有可能是同一个对象。(此处关于其他语言和Python中关于对象赋值的描述或许不是很准确,但这样有助于理解。)

>>> a=2570                   #理解:把a这个标签贴到值2570上
>>> b=a                      #理解:因为a=2570,b=a相当于把b这个标签贴到值2570上
>>> a
2570
>>> b
2570
>>> a is b
True                         #理解:结果为True,表明a和b是同一个对象

接上例,如果我们再把变量a和b分别赋其他的值,原来的对象2570还存在吗?

>>> a=2570                   #理解:把a这个标签贴到值2570上
>>> b=a                      #理解:因为a=2570,b=a相当于把b这个标签贴到值2570上
>>> a=1000                   #理解:相当于把a这个标签从2570上撕下,然后贴到1000这个值上
>>> b=2000                   #理解:相当于把b这个标签从2570上撕下,然后贴到2000这个值上
>>> a
1000
>>> b
2000

通过上面的代码,2570这个值上的标签全部重新贴给了其他值,也就是说2570不再有引用了,Python的垃圾回收机制会自动回收这个2570这个值,并清理这个值占用的内存。

一些特别的情况

>>> a=257
>>> b=257
>>> a is b
False

大多数情况下我们通过上面的方式对变量进行赋值都是创建了两个对象,但总有一些特别的情况。比如:

>>> a=50
>>> b=50
>>> a is b
True
>>> c='abc'
>>> d='abc'
>>> a is d
True

之所以出现上面的这种情况,这是因为Python对整型对象和字符串对象的缓存机制造成,这种缓存机制可以在一定程序上提高内存的效率,减少内存的占用。但这种缓存机制是有一定范围的,而且不同版本的Python其缓存范围也是不一样的。Python2.7.13对于整形对象的缓存范围是(-5,256),这是我自己测试出来的值,而关于字符串对象的缓存范围我没有查到相关资料。

其他判断对象身份的方法

可以使用id()内建函数获取对象的内存地址,通过判断内存地址是否相同来判断对象身份是否相同。

>>> b=a=1000
>>> a is b
True
>>> id(a)
57252448
>>> id(b)
57252448
>>> id(a)==id(b)
True
>>> c=1000
>>> d=1000
>>> c is d
False
>>> id(c)
57252496
>>> id(d)
57252460
>>> id(c)==id(d)
False

其他相关

关于对象的引用计数,可以自行查阅一下sys.getrefcount()相关的内容。

参考资料

  • 《Python核心编程》(第二版)
      Wesley J.Chun 著
       宋吉广 译
      人民邮电出版社出版发行
  • 《与孩子一起学编程》
      Warren Sande、Carter Sande  著
      苏金国、姚曜 等译
      人民邮电出版社出版发行**

相关文章

  • Python对象的身份比较

    相较于值的比较,Python也支持身份的比较。 身份比较运算符: 什么是身份比较 所谓身份比较,即判断两个或更多的...

  • 对象

    对象的身份与类型 python内置函数id()可返回该对象的在内存中的位置is 用于比较两个对象的身份type()...

  • Python高阶(持续更新中...)

    对象的比较 == 操作符比较对象之间的值是否相等在 Python 中,每个对象的身份标识,都能通过函数 id(ob...

  • Python对象

    1 python对象基础 1.1 python对象特征 身份:每一个对象都有一个唯一的身份标识自己,任何对象的身份...

  • Python基础3:对象和序列数据类型

    一、对象 所有的 Python 对象都拥有三个特性:身份,类型和值。 身份 对象的唯一标识,对象的身份可以使用内建...

  • Python核心编程,第四章习题

    4–1. Python 对象。与所有 Python 对象有关的三个属性是什么?请简单的描述一下。 身份:唯一身份标...

  • Python对象

    Python对象 Python对象有三个属性 身份: 这个值可以看作是该对象的内存地址, id(obj) 类型 :...

  • 这个概念是每一个学习Python的人必须掌握的知识点!

    1.函数的对象特性 Python中的所有对象都有3个特征:身份,类型和值. 身份:每个对象都有一个唯一的身份标识,...

  • python系列三——python对象

    1,python对象拥有三个特性:身份、类型和值。身份:每一个对象都有一个唯一的身份标识自己,任何对象的身份都可以...

  • 2018-07-24 比较、相等和真值

    所有的python对象都支持比较操作——测试相等性、相对大小等。python对象的比较是比较对象上所有的部分,即使...

网友评论

    本文标题:Python对象的身份比较

    本文链接:https://www.haomeiwen.com/subject/bauozttx.html