当我们创建一个对象时,我们要知道它内部干了些什么
a = 1
print(id(1))
print(id(a))
print(type(a))
结果
4470700832
4470700832
<class 'int'>
可以明显看出数字1的内存地址跟对象a的内存地址是一样的,a = 1
的原理是首先内存中有一个id=4470700832
,type=int
,value=1
的对象,然后创建a对象指向1,此时a的id、type、value跟1的一样
上面分析了创建对象的整个内存过程,那么接下来理解is和==的区别就好多了
__eq__()
方法。>>> a = 257
>>> b = 257
>>> id(a)
140204598140720
>>> id(b)
140204598140400
>>> print(a is b)
False
>>> print(a == b)
True
根据我们上面讲解的,a的地址和b的地址应该跟257的地址相同,但是现在显然不同,这是为什么呢?下面会说明
Python 仅仅对比较小的整数对象进行缓存(范围为[-5, 256])
缓存起来,而并非是所有整数对象。需要注意的是,这仅仅是在命令行中执行,而在Pycharm
或者保存为文件执行,结果是不一样 的,这是因为解释器做了一部分优化(范围是[-5,任意正整数])。
字符串驻留是一种仅保存一份相同且不可变字符串的方法。
基本原理
系统维护interned
字典,记录已被驻留的字符串对象。
当字符串对象a需要驻留时,先在interned
检测是否存在,若存在则指向存在的字符串对象,a的引用计数减1;
若不存在,则记录a到interned
中
>>> a = "hello" + "world"
>>> a is "helloworld"
True
>>> a = "hello"
>>> b = "world"
>>> a + b is "helloworld"
False
>>> a = "*"
>>> b = "*"
>>> a is b
True
>>> a = "**"
>>> b = "**"
>>> a is b
False
>>> a = "hello1_"
>>> b = "hello1_"
>>> a is b
True
>>> a = "hello!"
>>> b = "hello!"
>>> a is b
False
# 乘数=1,仅含大小写字母、数字、下划线驻留
>>> a = "abcdefghijklmnopqrstuvwxyz1234567890_ABCDXYZ"
>>> b = a * 1
>>> a is b
True
# 乘数=1,含其他字符,长度≤1,默认驻留
>>> a = "#"
>>> b = "#" * 1
>>> a is b
True
# 乘数=1,含其他字符,长度>1,则不驻留
>>> a = "##"
>>> b = "##" * 1
>>> a is b
False
## 仅含有大小写字母、数字、下划线,默认驻留
>>> a = "hellohellohellohellohellohellohello"
>>> b = "hello"*7
>>> a is b
True
# 含其他字符串,默认不驻留
>>> a = "&&&&"
>>> b = "&"*4
>>> a is b
False
>>> from sys import intern
>>> a = intern("hello#!")
>>> b = intern("hello#!")
>>> a is b
True
>>>
最后,当不满足标识符规则时,则不会启用驻留机制,当然这只出现在命令行中,如果你使用pycharm
则不会出现这样的情况,pycharm
内部已经帮我们做了处理
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/164950.html原文链接:https://javaforall.cn