在 Python 中会用到对象之间比较,可以用 ==,也可以用 is 。但是它们的区别是什么呢?

  • is 比较的是两个实例对象是不是完全相同,它们是不是同一个对象,占用的内存地址是否相同。莱布尼茨说过:“世界上没有两片完全相同的叶子”,这个is正是这样的比较,比较是不是同一片叶子(即比较的id是否相同,这id类似于人的身份证标识)。

  • == 比较的是两个对象的内容是否相等,即内存地址可以不一样,内容一样就可以了。这里比较的并非是同一片叶子,可能叶子的种类或者脉络相同就可以了。默认会调用对象的 __eq__()方法。

可以通过如下例子来区分比较下:

>>> a = ["I", "love", "Python"]
>>> b = a
# a的引用复制给b,在内存中其实是指向了用一个对象
>>> b is a
True
>>> id(a)
46381384
>>> id(b)
46381384
# 当然,内容也肯定是相等的
>>> b == a
True

可以发现b和a的内存地址是相同的,它们指向同一块内存,因而 is 和 == 的结果都为True。这是因为直接赋值都是赋值的引用,是引用,是引用,重要的事情说三遍。但如果不是通过引用赋值,而是通过切片赋值呢?

# b通过切片操作重新分配了对象,但是值和a相同
>>> b = a[:]
>>> b is a
False
>>> id(a)
48740680
>>> id(b)
48740680
>>> b == a # 但他们的值还是相等的
True

新建对象之后,b 和 a 指向了不同的内存,所以 b is a 的结果为False,而 b==a的结果为True。在这里,小编提一个问题,b[0] is a[0] 的结果呢?

答案是True。因为切片拷贝是浅拷贝,列表中的元素并未重新创建。不理解的同学请翻看之前的文章python中的浅拷贝和深拷贝。

通常,我们关注的是值,而不是内存地址,因此 Python 代码中 == 出现的频率比 is 高。但是什么时候用 is 呢?

is 与 == 相比有一个比较大的优势,就是计算速度快,因为它不能重载,不用进行特殊的函数调用,少了函数调用的开销而直接比较两个整数 id。而 a == b 则是等同于a.__eq__(b)。继承自 object 的 __eq__ 方法比较两个对象的id,结果与 is 一样。但是多数Python的对象会覆盖object的 __eq__方法,而定义内容的相关比较,所以比较的是对象属性的值。

在变量和单例值之间比较时,应该使用 is。目前,最常使用 is 的地方是判断对象是不是 None。下面是推荐的写法:

a is None

判断不是None的推荐写法是:

a is not None

Python会对比较小的整数对象进行缓存,下次用的时候直接从缓存中获取,所以is 和 == 的结果可能相同:

>>> a = 1
>>> b = 1
>>> a is b
True
>>> a == b
True

而看一下另外一段代码:

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

这是什么原因呢?

注意,Python仅仅对比较小的整数对象进行缓存(范围为范围[-5, 256])缓存起来,而并非是所有整数对象。需要注意的是,这仅仅是在命令行中执行,而在Pycharm或者保存为文件执行,结果是不一样的,这是因为解释器做了一部分优化。

总结

1、is 比较两个对象的 id 值是否相等,是否指向同一个内存地址;
2、== 比较的是两个对象的内容是否相等,值是否相等;
3、小整数对象[-5,256]在全局解释器范围内被放入缓存供重复使用;
4、is 运算符比 == 效率高,在变量和None进行比较时,应该使用 is。

python中的"is"与"=="比较的更多相关文章

  1. [转]Python中的str与unicode处理方法

    早上被python的编码搞得抓耳挠腮,在搜资料的时候感觉这篇博文很不错,所以收藏在此. python2.x中处理中文,是一件头疼的事情.网上写这方面的文章,测次不齐,而且都会有点错误,所以在这里打算自 ...

  2. python中的Ellipsis

    ...在python中居然是个常量 print(...) # Ellipsis 看别人怎么装逼 https://www.keakon.net/2014/12/05/Python%E8%A3%85%E9 ...

  3. python中的默认参数

    https://eastlakeside.gitbooks.io/interpy-zh/content/Mutation/ 看下面的代码 def add_to(num, target=[]): tar ...

  4. Python中的类、对象、继承

    类 Python中,类的命名使用帕斯卡命名方式,即首字母大写. Python中定义类的方式如下: class 类名([父类名[,父类名[,...]]]): pass 省略父类名表示该类直接继承自obj ...

  5. python中的TypeError错误解决办法

    新手在学习python时候,会遇到很多的坑,下面来具体说说其中一个. 在使用python编写面向对象的程序时,新手可能遇到TypeError: this constructor takes no ar ...

  6. python中的迭代、生成器等等

    本人对编程语言实在是一窍不通啊...今天看了廖雪峰老师的关于迭代,迭代器,生成器,递归等等,word天,这都什么跟什么啊... 1.关于迭代 如果给定一个list或tuple,我们可以通过for循环来 ...

  7. python2.7高级编程 笔记二(Python中的描述符)

    Python中包含了许多内建的语言特性,它们使得代码简洁且易于理解.这些特性包括列表/集合/字典推导式,属性(property).以及装饰器(decorator).对于大部分特性来说,这些" ...

  8. python cookbook 学习系列(一) python中的装饰器

    简介 装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象.它经常用于有切面需求的场景,比如:插入日志.性能测试.事务处理.缓 ...

  9. 用 ElementTree 在 Python 中解析 XML

    用 ElementTree 在 Python 中解析 XML 原文: http://eli.thegreenplace.net/2012/03/15/processing-xml-in-python- ...

  10. Python中操作mysql的pymysql模块详解

    Python中操作mysql的pymysql模块详解 前言 pymsql是Python中操作MySQL的模块,其使用方法和MySQLdb几乎相同.但目前pymysql支持python3.x而后者不支持 ...

随机推荐

  1. js 正则表达式简易教程

    (http://www.cnblogs.com/tugenhua0707/p/5037811.html#_labe6)

  2. wxpython 设置鼠标样式

    鼠标指针被设置为放大镜样式.可用的鼠标指针样式有: wx.CURSOR_ARROWwx.CURSOR_RIGHT_ARROWwx.CURSOR_BLANKwx.CURSOR_BULLSEYEwx.CU ...

  3. dwr2.0版本的demo

        谈起DWR,这个东西在上学的时候接触过,但工作之后就再也没有用过.       对DWR的印象是不手写AJAX,使用JavaScript调用java后台的代码,就如同调用前台代码一样.     ...

  4. C/C++:函数的调用约定(Calling Convention)和名称修饰(Decorated Name)以及两者不匹配引起的问题

    转自:http://blog.csdn.net/zskof/article/details/3475182 注:C++有着与C不同的名称修饰,主要是为了解决重载(overload):调用约定则影响函数 ...

  5. Mysql Order By 注入总结

    前言 最近在做一些漏洞盒子后台项目的总结,在盒子多期众测项目中,发现注入类的漏洞占比较大.其中Order By注入型的漏洞也占挺大一部分比例,这类漏洞也是白帽子乐意提交的类型(奖金高.被过滤概率小). ...

  6. KVM虚拟化学习记录

    请查看我的有道云笔记: http://note.youdao.com/noteshare?id=ed7308eeb1ee675b406494f4ba042ba4&sub=047FD8C61BA ...

  7. March 6 2017 Week 10 Monday

    A well-spent day brings happy sleep. 丰盈白日,安眠晚间. Recently my sleep is not so good, for one thing I go ...

  8. 用批处理在windows中导出/导入无线网络信息,复制保存为bat即可

    @echo offtitle 在windows中导出/导入无线网络信息 :Beginecho ========================echo 请选择操作:echo 1 查看可用的无线网络ec ...

  9. codeforces 609E Minimum spanning tree for each edge

    E. Minimum spanning tree for each edge time limit per test 2 seconds memory limit per test 256 megab ...

  10. lua 语句学习

    就如同C里的if else,while,do,repeat.就看lua里怎么用: 1.首先看if else t = {1,2,3} local i = 1 if t[i] and t[i] % 2 = ...