很少BB,直接上实例设计
(1) >>> a = 'hello' >>> b = 'hello' >>> print(id(a),id(b)) 2037326236784 2037326236784 >>> a = 'hello world' >>> b = 'hello world' >>> print(id(a),id(b)) 2037326180976 2037326180784 (2) >>> a = 'hello'*4 >>> b = 'hello'*4 >>> print(id(a), id(b)) 2037326166320 2037326166320 >>> a = 'hello'*5 >>> b = 'hello'*5 >>> print(id(a), id(b)) 2037326142960 2037326143040 (3) >>> a = ' ' # 字符串中有一个空格 >>> b = ' ' # 字符串中有一个空格 >>> print(id(a), id(b)) 2037324558664 2037324558664
有朋友可能碰到这些状况时纳闷,怎么肥四?其实这是Python字符串的intern机制的锅,该机制规定:当两个或以上的字符串变量它们的值相同且仅由数字字母下划线构成并且长度在20个字符之内,或者值仅含有一个字符时,内存空间中只建立一个对象来让这些变量都指向该内存地址。当字符串不知足该条件时,相同值的字符串变量在建立时都会申请一个新的内存地址来保存值。code
Python字符串有intern机制的限制,一样的,整形数也有大小整数对象池的限制。Python语言在设计之初为了减小频繁申请和销毁内存的资源开销,规定了[-5, 256]之间的整数所有常驻在内存中且不会被垃圾回收只能增减引用计数,这就是小整数对象池,池外的数在建立时每次都得申请新的内存空间而不是增长引用计数。例子以下:对象
>>> a = 256 >>> b = 256 >>> print(id(a), id(b)) 1953505712 1953505712 >>> a = 257 >>> b = 257 >>> print(id(a), id(b)) 2037325924592 2037325924368
在交互式终端环境中,每次建立大型数时都是去申请新的内存空间。可是在编写Python文件时每次运行都把代码加载到内存中,整个项目代码都属于一个总体。这时就是大型整数对象池发挥做用的时候了,它把处于相同代码块的全部等值的大型整数变量都处理为一个对象。不懂就看实例。内存
class A(object): a = 100 b = 100 c = 1000 d = 1000 class B(object): a = 100 b = 1000 print(A.a is A.b) # True print(A.a is B.a) # True print(A.c is A.d) # True 重点是这一个 print(A.b is B.b) # False
瞅见了吧,类A和类B在同一文件中,虽然1000超出了[-5, 256]的范围可是仍是把他们处理成同一个对象了。资源
扩展点Python内存管理方面的姿式吧,我也是刚看到的,顺便贴这儿了,但愿对大家有用。字符串
>>> id([1,2,3]) == id([4,5,6]) True >>> a = [1,2,3] >>> b = [4,5,6] >>> print(id(a), id(b)) 2037326252488 2037326229256
有人问为何id([1,2,3]) == id([4,5,6]),这是由于Python会实时销毁没有引用计数的对象。一旦在内存中建立了一个对象可是没有为其添加引用计数,该段代码执行完后就会回收地址,在这个例子中计算完[1,2,3]的id后list被销毁,计算右边的id时list实时建立,复用了左边list用过的内存。可是生成的时间有前后,他们并不表明同一个对象。内存管理