python对象引用_一切都是对象

来源:互联网 发布:怎样改淘宝密码 编辑:程序博客网 时间:2024/06/11 06:40
  1. 对象是在内存中实实在在的,在内存中有一个地址存放他的内容的。
  2. 引用可以理解成对这个对象的地址,或者这个对象的名字

python中有一句话是“python中一切都是对象”,整数在python中是一个整数对象。整数相当于java中的Integer类,而不是int。
a = 1 // 1是对象,a是这个对象的引用

在python中有两个运算符 == 和 is,前者用于比较对象的值,后者用于比较两个对象是不是同一个

例子:

““

a=1000
b=1000
a == b
True
a is b
False

id(a)
140524223738936
id(b)
140524223738984
id(1000)
140524223738864

点评: a指向一个对象1000 ,b指向另外一个对象1000a 和 b 值相等,但是两者不是同一个对象的引用创建了两个对象1000,通过id()可以获取一个对象在内存中地址

““

例子:

““

a=1000
b=a
a == b
True
a is b
True
id(a)
140524223738864
id(b)
140524223738864
id(1000)
140524223738960

点评:第二步将a赋值给b,实际效果相当于b和a同时指向同一个对象1000,因此id(a)和id(b)相等,a is b 返回True

““

例子:

““

a=2
b=2
a == b
True
a is b
True
id(a)
140524220614464
id(b)
140524220614464
id(2)
140524220614464

a=”a”
b=”a”
id(a)
4471174648
id(b)
4471174648
id(“a”)
4471174648

点评:    对于[-5,255]内的整数和单字符的字符串在python启动的时候就会创建好对象,因此a=2和b=2实际都只有一个对象2(节省了内存申请和释放的开销)    对于大整数都是实时创建和销毁的,如果要长期保存大整数会有内存问题,事实上python中整数对象池是只增不减的。如果代码运行到某一时刻同时存在成千上万的整数对象,那么之后即使不用了,内存也会居高不下,这点在数值计算时需要特别注意    上面一个例子中id(1000)和id(a)不同,代表a=1000创建了2个对象,分配了2块内存,一个是1000,另一个是指向对象1000的引用a。    而本例中从id(a)和id(2)相同,why???

““

例子:容器里的对象
python中存放的一切对象都是引用。

((1111,2222,3333),(4444,5555,6666)) 这个元祖在内存中布局是:    1. 整体上这是一个元祖,里面的两个元素也都是元祖,因此内存中会有2个内存块存放这两个元祖的地址    2. 每一个元祖元素又包含3个整数对象,因此会有3个内存块存放三个整数对象的引用,另外还会有3个内存块存放整数对象本身

例子:extend和+=的区别

- 区别1:>>> import dis>>> def f1():...     l1+=[2]...>>> dis.dis(f1)  2           0 LOAD_FAST                0 (l1)          3 LOAD_CONST               1 (2)          6 BUILD_LIST               1          9 INPLACE_ADD         10 STORE_FAST               0 (l1)         13 LOAD_CONST               0 (None)         16 RETURN_VALUE>>>>>> def f2():...     l1.extend([2])...>>> dis.dis(f2)2           0 LOAD_GLOBAL              0 (l1)          3 LOAD_ATTR                1 (extend)          6 LOAD_CONST               1 (2)          9 BUILD_LIST               1         12 CALL_FUNCTION            1         15 POP_TOP         16 LOAD_CONST               0 (None)         19 RETURN_VALUE>>>- 共同点:>>> l1=[]>>> l1+=t1>>> l1[1, 2, 3]>>> l1.extend(t1)>>> l1[1, 2, 3, 1, 2, 3]说明:1. dis模块可以将python代码反编译出来,写成类似汇编指令的形式。2. += 是个内置的运算操作,extend是个函数,涉及到函数查找,入栈出栈,前者效率更高些3. +=和extend达到的效果一样,都是对list的本地延伸,后面被+=的对象或者extend的参数只要可以遍历即可,不一定是list,可以是tuple等

例子:不可变对象

>>> t=(1,2)>>> id(t)4553455016>>> t2=(3,)>>> t+=t2>>> t(1, 2, 3)>>> id(t)4553522144>>>1. python中不可变对象只有: int ,float,str,tuple,complex。2. 要想改变这些对象只有新建一个新的对象,将引用指向新的对象,实际原来的对象本身并没有改变。因此当使用tuple来做需要经常改变内容的数组,会造成很大的效率问题3. 不能对不可变对象的元素进行赋值,如下:>>> t[0]=5Traceback (most recent call last):File "<stdin>", line 1, in <module>TypeError: 'tuple' object does not support item assignment>>>4. 字典的key值是必须是不可变对象,>>> l=[]>>> t=(1,)>>> d={t:"123"}>>> d={l:"123"}Traceback (most recent call last):File "<stdin>", line 1, in <module>TypeError: unhashable type: 'list'

例子:

>>> t=(1)>>> type(t)<type 'int'>>>> t=(1,)>>> type(t)<type 'tuple'>说明:    只有一个元素的tuple,该元素后要加一个逗号,否则就是个整数类型,而不是tuple

例子:

>>> l=[[]]*9>>> l[[], [], [], [], [], [], [], [], []]>>> l=[[]]*9>>> l[[], [], [], [], [], [], [], [], []]>>> l[0].append(1)>>> l[[1], [1], [1], [1], [1], [1], [1], [1], [1]]>>> l[1].append(2)>>> l[[1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2], [1, 2]]>>>说明:1、 l中的每个元素都是list,因此都是引用,*9实际是将第一个元素的引用复制了9次。因此改变了l[0],大家都变了2. python中对象的赋值,传递都是引用的传递赋值。除非使用copy库中的接口,可以强制指定复制3. [[]]*9 等价于 :    l=[]    t=[]    for i in xrange(9):        l.append(t)    要想实现9个不同的空列表,可以这样:    l=[]    for i in xrange(9):        l.append([])   //每次都会创建一个新的[]    简写成:[[] for i in xrange(9)]4. >>> l=[[]]>>> id(l)4553610736>>> l=l*10   //赋值操作意味着两件事儿,new一个对象,>>> id(l)4553611312>>> l=[[]]>>> id(l)4553610088>>> l *= 10>>> id(l)4553610088>>>*= 操作 id不变,

例子:

>>> def f(a,L=[]):...     L.append(a)...     print L...>>> f(1)[1]>>> f(2)[1, 2]>>>说明:L的默认值是和f绑定在一起的,每次调用f的时候都用L来引用,这个列表是在建立f的时候创建的。python在碰到def时,会将下面的“代码对象”关联到函数名的引用。每次执行的时候只是将L引用到这个对象,并不会重新建立一个新的列表然后将引用赋给L

例子:

def f(g):
… g()

def h():
… print “I am h”

f(h)
I am h

说明:函数def和变量赋值本质上没有任何区别。函数f就是对一个函数对象的引用,跟a=1是表示a对对象1的引用一样。因此可以执行g=f,通过g()来调用f(),另外函数对象也可以像其他对象一样作为参数传递
0 0
原创粉丝点击