python 的 is 与 == 区别
2018-03-11 11:02
197 查看
输入如下代码
"is" 比较的是两个实例对象是不是完全相同,它们是不是同一个对象,占用的内存地址是否相同。莱布尼茨说过:“世界上没有两片完全相同的叶子”,这个is正是这样的比较,比较是不是同一片叶子(即比较的id是否相同,这id类似于人的身份证标识)。
"==" 比较的是两个对象的内容是否相等,即内存地址可以不一样,内容一样就可以了。这里比较的并非是同一片叶子,可能叶子的种类或者脉络相同就可以了。默认会调用对象的 __eq__()方法。
可以通过 id 来查询分辨两个实例对象是否相同>>> id(b)
2479316523720
>>> id(c)
2479316523912
>>> id(d)
2479316523720这个其实就跟深浅层copy的原理很类似了。
整形数据
在python IDE中,-5~256 范围的整形数,内存地址是缓存好的。如果超出这个范围,多次引用内存地址会发生变化。>>> id(-6)
2479315586096
>>> id(-6)
2479315584432
>>> id(-5)
1524002080
>>> id(-5)
1524002080字符串
字符串算是进程里实例数量较多的类型之一,因为无处不在的名字就是字符串实例。鉴于相同名字会重复出现在各种名字空间里,那么有必要让它们共享对象。内容相同,且不可变,共享不会导致任何问题。关键是可节约内存,且省去创建新实例的调用开销。对此,Python 的做法是实现一个字符串池(intern)。池负责管理实例,使用者只需引用即可。另一潜在好处是,从池返回的字符串,只需比较指针就可知道内容是否相同,无需额外计算。可用来提升哈希表等类似结构的查找性能。>> > "__name__" is sys . intern ( "__name__" )True除了以常量方式出现的名字和字面量外,动态生成字符串一样可加入池中。如此可保证每 次都引用同一对象,不会有额外的创建和分配操作。>> > a = "hello, world!">> > b = "hello, world!">> > a is b # 不同实例。False>> > sys . intern ( a ) is sys . intern ( "hello, world!" ) # 相同实例。True当然,一旦失去所有外部引用,池内字符串对象会被回收。>> > a = sys . intern ( "hello, world!" )>> > id ( a )4401879024>> > id ( sys . intern ( "hello, world!" ) ) # 有外部引用。4401879024>> > del a # 删除外部引用后被回收。>> > id ( sys . intern ( "hello, world!" ) ) # 从 id 值不同可以看到新建,入池。4405219056字符串池实现算法很简单,就是简单的字典结构。 详情参考 Objects/unicodeobject.c : PyUnicode_InternInPlace。做大数据处理时,可能需创建海量主键,使用 intern 有助于减少对象数量,节约大量内存。
>>> b = [0, 1] >>> c = b[:] >>> d = b
>>> print(b is c) False >>> print(b is d) True为什么会有如上结果呢?
"is" 比较的是两个实例对象是不是完全相同,它们是不是同一个对象,占用的内存地址是否相同。莱布尼茨说过:“世界上没有两片完全相同的叶子”,这个is正是这样的比较,比较是不是同一片叶子(即比较的id是否相同,这id类似于人的身份证标识)。
"==" 比较的是两个对象的内容是否相等,即内存地址可以不一样,内容一样就可以了。这里比较的并非是同一片叶子,可能叶子的种类或者脉络相同就可以了。默认会调用对象的 __eq__()方法。
可以通过 id 来查询分辨两个实例对象是否相同>>> id(b)
2479316523720
>>> id(c)
2479316523912
>>> id(d)
2479316523720这个其实就跟深浅层copy的原理很类似了。
整形数据
在python IDE中,-5~256 范围的整形数,内存地址是缓存好的。如果超出这个范围,多次引用内存地址会发生变化。>>> id(-6)
2479315586096
>>> id(-6)
2479315584432
>>> id(-5)
1524002080
>>> id(-5)
1524002080字符串
字符串算是进程里实例数量较多的类型之一,因为无处不在的名字就是字符串实例。鉴于相同名字会重复出现在各种名字空间里,那么有必要让它们共享对象。内容相同,且不可变,共享不会导致任何问题。关键是可节约内存,且省去创建新实例的调用开销。对此,Python 的做法是实现一个字符串池(intern)。池负责管理实例,使用者只需引用即可。另一潜在好处是,从池返回的字符串,只需比较指针就可知道内容是否相同,无需额外计算。可用来提升哈希表等类似结构的查找性能。>> > "__name__" is sys . intern ( "__name__" )True除了以常量方式出现的名字和字面量外,动态生成字符串一样可加入池中。如此可保证每 次都引用同一对象,不会有额外的创建和分配操作。>> > a = "hello, world!">> > b = "hello, world!">> > a is b # 不同实例。False>> > sys . intern ( a ) is sys . intern ( "hello, world!" ) # 相同实例。True当然,一旦失去所有外部引用,池内字符串对象会被回收。>> > a = sys . intern ( "hello, world!" )>> > id ( a )4401879024>> > id ( sys . intern ( "hello, world!" ) ) # 有外部引用。4401879024>> > del a # 删除外部引用后被回收。>> > id ( sys . intern ( "hello, world!" ) ) # 从 id 值不同可以看到新建,入池。4405219056字符串池实现算法很简单,就是简单的字典结构。 详情参考 Objects/unicodeobject.c : PyUnicode_InternInPlace。做大数据处理时,可能需创建海量主键,使用 intern 有助于减少对象数量,节约大量内存。
相关文章推荐
- 从Python对象三要素来看is和==的区别
- Python自学之is和‘==’的区别
- python中==和is的区别
- python中is 与 == 的区别
- Python中is和==的区别
- Python is同一性运算符和==相等运算符区别
- python 包和模块 等于号(==)和is的区别与联系 对象的拷贝(copy)
- python中运算符‘is’,'is not'和‘==’,’!=‘的区别
- Python中is和==的区别
- Python陷阱之 is 和 == 区别
- Python中is和==的区别和联系
- Python 中的None以及 == 与 is 的区别,以及判断某个list或者dict元素是否为None
- Python is和==的区别
- [基础] - Python中 is 和 == 的区别
- Python3 关键字 in 和 is 的区别
- Python中 == 与 is 的区别和应用场景
- python3 ==和is的区别
- Python中is和==的区别
- Python中is和==的区别
- Python 类型判断 变量存在判断 None与空字符串 is和==区别 nan inf判断