导读:Python中不明确区分赋值和应用,一般对静态变量的传递为赋值,对动态变量的传递为引用。(注,对静态变量首次传递时也是应用,当需要修改静态变量时,因为静态变量不能改变,所以需要生成一个新的空间存储数据)个人觉得分清楚规则即可比较容易的区别。 Python中不明确区分赋值和应用,一般对静态变量的传递为赋值,对动态变量的传递为引用。(注,对静态变量首次传递时也是应用,当需要修改静态变量时,因为静态变量不能改变,所以需要生成一个新的空间存储数据)个人觉得分清楚规则即可比较容易的区别。 字符串,整数,元组均为静态变量 列表,字典为动态变量。 以下示例在Python 2.7环境下演示,id()函数可显示变量内存地址 例1:整数传递a = 4print id(a) #id函数显示变量内存地址 b = a print id(b) b = 6 print id(b) >>> 19691376 19691376 19691328 说明, 例2:变量传递a = "mm"print id(a) b = a print id(b) b = "nn" print id(b) >>> 37313312 37313312 37313352 说明: 1.a为一个指向字符串的变量名 2.a传递给b时,b为一个引用指向和a相同的地址 3.当b被赋给一个新字符串值时,因为b指向的"mm"是一个静态变量,所以生成一个新空间存放"nn",然后b指向"nn" 例3:列表的地址存储(以下为个人理解,未查源代码,如有错误请指正)>>> 说明: 从输出的1,2,3行看出,a的地址>a[0]的地址>a[1]的地址,而且a[0]和a[1]地址间相差较远,所以python中的列表绝对不是c中的数组,应该是个链表。(从python列表具有append()函数也可以看出) 命令第5行a传递给b时,从输出6,7行看,a和b指向了同一个地址,b为a的一个引用,a,b的值应该是指向链表头的指针。 命令第6行,b[0]值发生改变,从输出4,5行看,a,b内容同时都发生改变,从输出6,7行a,b指向的还是同一个地址,从输出7行看a[0]的地址发生了改变,所以应该时链表的第一个节点被替换(即使变量类型兼容),所以也可以理解为什么python可以不关注变量类型。输出第8行为a[1]的地址,没有发生改变 命令第13行,b[1]被改变,分析同上,a,b指向的同一个链表的尾元素被替换 例4:列表传递(引用)a = [4]print id(a) b = a print id(b) b[0] = 6 print id(b) >>> 43351720 43351720 43351720 说明; 同上例理解 例5:列表赋值a = [4]print id(a) b = a[:] print id(b) b[0] = 8 print id(b) >>> 22863528 23030888 23030888 说明: 1.a指向一个动态变量列表 2.b得到a列表的一个copy存储在一个新的空间,b指向一个新地址(b = a 和b=a[:]的区别可从 ,b=a,b=a[1:3]的区别进行理解) 3.b的第一个元素赋值8,不影响a 例6:字典引用a = {"i":99}print id(a) b = a print id(b) b["o"] = 8 print id(b) print "a=", a print "b=", b >>> 28841616 28841616 28841616 a= {'i': 99, 'o': 8} b= {'i': 99, 'o': 8} 说明: 1.a指向一个动态变量 2.b为a的一个引用 3.b新增了一个变两,a也新增 例7:字典赋值a = {"i":99}print id(a) b = a.copy() print id(b) b["o"] = 8 print id(b) print "a=", a print "b=", b >>> 16033424 16063424 16063424 a= {'i': 99} b= {'i': 99, 'o': 8} 说明: 1.a指向一个动态变量 2.b为a的一个拷贝,指向一个新地址 3.b新增了一个变量,a不变 例8:不同类型变量传递a = "mm" >>> 11687096 说明: 1.a指向一个静态 2.b为a的一个应用,指向和a相同的地址 3.b发生了改变,指向一个新的数据地址
总结:a = "mm"print id(a)b = aprint id(b)b = 8print id(b)print "a=", aprint "b=", b |
|