Python中is与==的使用区别详解

目录
  • 一、== 是比较两个对象的内容是否相等
  • 二、is 比较的是两个实例对象是不是完全相同
  • 三、使用is注意python对于小整数使用对象池存储问题
  • 四、使用is注意python关于字符串的intern机制存储
  • 5.python中对于None值的比较:使用is

一、== 是比较两个对象的内容是否相等

即两个对象的“值“”是否相等,不管两者在内存中的引用地址是否一样。

//地址一样,值也一样。所以==成立。

st1 ='aaaaa'
st2 = 'bbbbb'
st3 = 'bbbbb'
st4 = st3
print(st1==st2,st2==st3,st3==st4)#False True True
print(id(st2)==id(st3),st2==st3) #True True  

//引用地址不一样,但是只要值一样即可==成立。

>>> val1 = 2000
>>> val2 = 2001
>>> val3 = val1 +1
>>> print(id(val3)==id(val2),val3==val2)
False True

//对于类的实例比较

class Student(object):
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def run(self):
        print("can run")

stu1 = Student("tom",19)
stu2 = Student("tom",19)
stu3 = stu2
print(id(stu1)==id(stu2),stu1 == stu2)  #False False

注意:这里stu1stu2的值是不等的,虽然初始化创建对象格式一样。

print(id(stu2)==id(stu3),stu2 == stu3)  # True True

二、is 比较的是两个实例对象是不是完全相同

它们是不是同一个对象,占用的内存地址是否相同。即is比较两个条件:1.内容相同。2.内存中地址相同

//is成立的前提要是内容相同,内存中地址相同

st1 ='aaaaa'
st2 = 'bbbbb'
st3 = 'bbbbb'
st4 = st3
print(st1 is st2, st2 is st3,st3 is st4)#False True True
print(id(st1),id(st2),id(st3),id(st4))
#2439382008080 2439382008192 2439382008192 2439382008192

//光值相同不同,内存地址也要相同,才会成立。

>>> a = 1
>>> a = 1000
>>> b = 1000
>>> print(id(a),id(b))
2625727620144 2625727619248
>>> print(a is b)
False
>>> print(a ==b)
True
>>>

//类实例的比较,也要内存地址一致。

class Student(object):
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def run(self):
        print("can run")

stu1 = Student("tom",19)
stu2 = Student("tom",19)
stu3 = stu2
print(id(stu1),id(stu2),id(stu3))
print(stu1 is stu2,stu2 is stu3)
=========================================
2091922655776 2091922655888 2091922655888
False True

三、使用is注意python对于小整数使用对象池存储问题

举个例子,在python命令行模式下:为什么同样值a,b与c,d的结果却不一样呢?

>>> a = 1000
>>> b = 1000
>>> a is b
False
>>> c = 10
>>> d = 10
>>> c is d
True

注意:因为python对小整数在内存中直接创建了一份,不会回收,所有创建的小整数变量直接从对象池中引用他即可。
但是注意Python仅仅对比较小的整数对象进行缓存(范围为范围[-5, 256])缓存起来,而并非是所有整数对象。
也就说只有在这个[-5,256]范围内创建的变量值使用is比较时候才会成立。

>>> e ,d ,f ,g = -5 ,-5 ,-6 ,-6
>>> e is d
True
>>> f is g  #超过-5的范围不成立
False
>>>

注意:上面对于python小整数对象池的使用仅仅是在命令行中执行可以,而在Pycharm或者保存为文件执行,结果是不一样的,这是因为解释器做了一部分优化。下面使用pycharm,即使整数超过256,使用is也是成立的。

四、使用is注意python关于字符串的intern机制存储

注意:python中创建两个内容一样的变量时(变量名不一样),一般都会在内存中分配两个内存地址分别给这两个变量。即两个变量的内容虽然样,但是变量的引用地址不一样。所以两个变量使用==比较成立,但是使用 is比较不成立。

但是在python中有两个意外情况:

  1. 使用python命令行时对于小整数[-5,256]区间内的整数,python会创建小整数对象池,这些对象一旦创建,就不会回收,所有新创建的在这个范围的整数都是直接引用他即可。所以造成在[-5,256]区间内的整数不同变量只要值相同,引用地址也相同。此范围外的整数同样遵循新建一个变量赋予一个地址。
  2. python中虽然字符串对象也是不可变对象,但python有个intern机制,简单说就是维护一个字典,这个字典维护已经创建字符串(key)和它的字符串对象的地址(value),每次创建字符串对象都会和这个字典比较,没有就创建,重复了就用指针进行引用就可以了。相当于python对于字符串也是采用了对象池原理。

(但是注意:如果字符串(含有空格),不可修改,没开启intern机制,不共用对象。比如"a b"和"a b",这种情况使用is不成立的形式 只有在命令行中可以。使用pycharm同样是True,因为做了优化)

>>> a ='abc'   #没有空格内容一样的两个变量,在命令行模式下is 结果True
>>> b = 'abc'
>>> a ==b
True
>>> a is b
True
>>> c ='a b '   #有空格内容一样的两个变量,在命令行模式下is 结果false
>>> d= 'a b '
>>> c ==d
True
>>> c is d
False

总结:

所以在python中如果创建了多个变量(不同变量名,此外不是通过变量引用方式创建的变量),那么这些变量的引用地址都是不一样的。那么这些变量之间使用is 去比较的话,就是False的结果。但是除了小整数和字符串除外。如果是通过引用的方式创建的变量的话,那么可以参考
变量引用在内存中的复制存储原理博客:关于python变量的引用以及在底层存储原理

>>> ls =[1,2,3]  ###值虽然一样,但是两个变量,内存中分配了两个地址。
>>> ls1 =[1,2,3]
>>> ls == ls1
True
>>> ls is ls1
False

>>> t1 = (1,2,3) ##值虽然一样,但是两个变量,内存中分配了两个地址。
>>> t2 = (1,2,3)
>>> t1 == t2
True
>>> t1 is t2
False

>>> d1 ={"1":2,"3":  ##值虽然一样,但是两个变量,内存中分配了两个地址。
>>> d2 ={"1":2,"3":
>>> d1 == d2
True
>>> d1 is d2
False
>>> id(d1),id(d2)
(5425744, 4537872)

>>> st1 ='abc'  #注意这里st1 和st2,值一样,内存地址也一样。因为字符串的intern机制。
>>> st2 ='abc'
>>> st1 == st2
True
>>> st1 is st2
True

>>> f1 = 3.14 #值虽然一样,但是两个变量,内存中分配了两个地址。
>>> f2 = 3.14
>>> f1 == f2
True
>>> f1 is f2
False

>>> a = 1000 #超出[-5,256]范围值虽然一样,但是两个变量,内存中分配了两个地址。
>>> b = 1000
>>> a is b ,a ==b
(False, True)

>>> a = 1  #值在小整数对象池范围内,所以值一样,内存地址一样。
>>> b = 1
>>> a is b ,a ==b
(True, True)
>>>

5.python中对于None值的比较:使用is

>>> a =""
>>> a is None
False
>>> b ="aa"
>>> b is None
False
>>> b is not None
True

到此这篇关于Python中is与==的使用区别详解的文章就介绍到这了,更多相关Python中is与==的使用区别内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 关于python变量的引用以及在底层存储原理

    目录 1.变量的引用的底层原理 2.变量的分类 Python的变量,简单来说有数值型,布尔型,字符串类型,列表,元组,字典等6大类.那么不同变量类型在底层是如何存储的,关系到变量的引用,能否正确的掌握变量的相关操作 下面v1,v2的值分别是多少?为什么? v1 =3 v2=v1 print("v2:",v2) v1 += 2 print("v1:",v1) print("v2:",v2) #下面l2的值又是多少?为什么? l1 = [1,2,3]

  • 童年回忆录之python版4399吃豆豆小游戏

    目录 前文 正文 结尾 前文 昨天家里来人,老姐的小孩儿抢着跟我玩电脑,result........很久很久之后!! 那你想错了,我可不是欺负小孩子的那种人.老实人本人.三秒之后就给她了. 看见她在4399玩了一款小游戏,感觉很适合小孩子.emmmmmm...... ​ 灵感来了挡都挡不住,嗯哼~今天正入正题,开发一款4399类似的吃豆豆小游戏,等着!!!! 正文 Python版本:3.6.4 相关模块: pygame模块: 以及一些Python自带的模块. 模块自行安装.环境安装包等新手小白不

  • Python中优雅使用assert断言的方法实例

    目录 什么是 assert 断言 断言和异常的使用场景 使用断言的几个原则 建议不使用断言的情况: 总结 什么是 assert 断言 Assert statements are a convenient way to insert debugging assertions into a program 断言声明是用于程序调试的一个便捷方式.断言可以看做是一个 debug 工具,Python 的实现也符合这个设计哲学,在 Python 中 assert 语句的执行是依赖于__debug__这个内置

  • python游戏的魅力之冒险岛实战项目

    目录 导语 正文 效果图: 总结 导语 ​哈喽哈喽!我是木木子. 新的一天又开始了~ ​ 是的,今天是大工程,​又到了每日更新游戏环节,你们有期待吗? ​ 想了很久,这游戏估计你们也没玩过,比较少见吧!最近家里的孩子一直在沉迷<梦幻国度>. 让他见识下python的魅力,能学习也能做游戏的.不能一直玩撒~学习也很重要嘛 今天想说我们直接开始制作一款Python玛丽冒险岛游戏~ 正文 ​ ​(1)环境安装部分: Python版本:Python 3.6 开发工具:PyCharm.Python内置模

  • python共享引用(多个变量引用)示例代码

    复制代码 代码如下: a = 3b = a 先上图(图1)吧,大家一看就一目了然了: 变量名和对象,在运行赋值语句b = a之后,变量a,b都指向了对象3的内存空间.假设这时执行 a = 'python', a将指向刚创建的字符串对象.我们再来试试这种情况: 复制代码 代码如下: >>>list_1 = [1,2,3,4]>>>list_2 = list_1>>>list_2>>>list_1[0] = 'python'>>

  • 聊聊Python中的@符号是什么意思

    Python中的@符号是装饰器的意思.Python中装饰器本质上就是一个函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外的功能,装饰器的返回值也是一个函数对象(函数的指针). 实质:是一个函数 参数:是你要装饰的函数名(并非函数调用) 返回:是装饰完的函数名(也不是函数调用) 作用:为已经存在的对象添加额外的功能. 特点:不需要对对象做任何的代码上的变动. Python装饰器有很多经典的应用场景,比如:插入日志,性能测试,事务处理,权限校验等.装饰器是解决这类问题的绝佳设计. 装饰器

  • python 如何将字典写为json文件

    目录 python 将字典写为json文件 字典结构如下 写为json Python txt文件读取写入字典(json.eval) 使用json转换方法 使用str转换方法 python 将字典写为json文件 字典结构如下 res = { "data":[] } temp = { "name":name, "cls":cls } res["data"].append(temp) 写为json 具体代码如下: json_dat

  • python游戏实战项目之俄罗斯方块的魅力

    目录 导语 正文 效果图: ​总结 导语 ​ 为什么有这么一个简单的游戏?这个游戏如此受欢迎? 仅仅是因为它在游戏行业异常匮乏的年代出现,从而成为了一代人的记忆吗?恐怕并不是. 玩过俄罗斯方块的人都明白,它给人的感觉就像是嗑瓜子一样,一旦开始就会像上瘾一样难以停下来,绞尽脑汁只想填满空缺的地方. ​ 哈哈哈!小编每周的话基本上都会整理一些游戏代码的哈! 这一期文章就带大家来开发一款俄罗斯方块小游戏! 正文 游戏规则:由小方块组成的不同形状的板块陆续从屏幕上方落下来,玩家通过调整板块的位置和方向,

  • python 基于 tkinter 做个学生版的计算器

    目录 导语 正文 总结 导语 九月初家里的熊孩子终于开始上学了! 半个月过去了,小孩子每周都会带着一堆的数学作业回来,哈哈哈哈~真好,在家做作业就没时间打扰我写代码了. 很赞,鹅鹅鹅饿鹅鹅鹅~曲项向天歌~~~~开心到原地起飞. 孩子昨天回家之后吃完饭就悄咪咪的说,神神秘秘的我以为做什么?结果是班主任让他们每个人带一个计算器,平常做数学算数的时候可以在家用用,嗯哼~这还用卖嘛? 立马给孩子用Python制作了一款简直一摸一样的学生计算器~ ​​ 正文 本文的学生计算器是基于tkinter做的界面化

  • python全局变量引用与修改过程解析

    这篇文章主要介绍了python全局变量引用与修改过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 一.引用 使用到的全局变量只是作为引用,不在函数中修改它的值的话,不需要加global关键字.如: #! /usr/bin/python a = 1 b = [2, 3] def func(): if a == 1: print("a: %d" %a) for i in range(4): if i in b: print(&quo

  • Python 多继承中的一个诡异现象 既是 Father又是grandfather

    目录 我们知道,在面向对象编程里面, 继承 是一个很重要的概念.子类可以使用父类的方法和属性. 例如下面这段代码: class Father: def __init__(self): self.address = '上海' def say(self): print('我是爸爸') class Son(Father): def __init__(self): super().__init__() def say(self): print('我是儿子') son = Son() print(son.

  • python游戏实战项目之童年经典超级玛丽

    导语 "超级玛丽"--有多少人还记得这款经典游戏?那个戴帽子的大胡子穿着背带裤的马里奥! 带您重温经典的回忆,超级马里奥拯救不开心!炫酷来袭. 如果您的童年,也曾被魔性的 灯~灯灯~灯~灯灯~灯洗脑~那就来怀旧一番吧! 我是华丽的分割线------------------------------ 往期写过游戏实战已经积累到30几篇了哦~嘿嘿,推一波之前的,狗头保命.jpg. 欢迎大家来领免费的游戏,开玩啦~源码可以直接找我拿滴! 在座的各位大佬,你们都玩过这里面的几个游戏吖? ​ 往期

随机推荐